Ad

Pass In Hard Coded Params Into Named Laravel Route

- 1 answer

I am creating some hard coded routes that will likely be changed again freely in the future. To abstract the ideas a bit:

We have a controller/method [email protected]:

class BuySubscriptionController
    function start()
    {
        $plan = Plan::findBySlug($request->get('plan'));

        return view('someView', ['plan' => $plan]);
    }
}

We currently have the following route:

Route::get('/buy-subscription/start', '[email protected]');

This means the sales team would need to advertise the following urls:

site.com/buy-subscription/start?plan=plan-one
site.com/buy-subscription/start?plan=plan-two

Now we have been requested to have a few specialized routes:

site.com/purchase/the-basic-plan (plan-one)
site.com/purchase/the-mega-plan (plan-two)

Now I am trying to add these specialized urls to my routes. I was hoping to do something as follows, but does not work:

Route::get('/purchase/the-basic-plan', [
   'uses' => '[email protected]', 
   'with' => ['plan' => 'plan-one']
]);

Route::get('/purchase/the-mega-plan', [
   'uses' => '[email protected]', 
   'with' => ['plan' => 'plan-two']
]);

Is there any way to achieve this, simply, without over engineering some new translation layer? Keep in mind that next week the url might be /buy/the-god-plan meaning plan-one, so being able to simple add a line to my routes seems ideal.

Ad

Answer

You can define a route that takes the plan as a parameter, and use Regular Expression Constraints so that parameter can only take certain values that you allow. So your route definition can look like this:

Route::get('/purchase/{plan}', '[email protected]')
     ->name('purchase-plan')
     ->where('plan', 'the-basic-plan|the-mega-plan');

Then in your controller action just use the parameter:

class BuySubscriptionController
{
    protected $plans = [
        'the-basic-plan' => 'plan-one',
        'the-mega-plan'  => 'plan-two'
    ];

    function start($plan)
    {
        // You can use an associative array to convert the $plan parameter
        // into the value you need for querying the database
        $plan = Plan::findBySlug($this->plans[$plan]);

        return view('someView', ['plan' => $plan]);
    }
}

If you need to generate URLs for the route you can just use the route helper method and pass it the plan name:

route('purchase-plan', 'the-basic-plan');

And you'll get:

site.com/purchase/the-basic-plan

This solution allows you to add any number of plan names by just adding the public plan for the URL in the where constraint of the route, then associating that value with the one you need for the query in your controller's $plans property.

Ad
source: stackoverflow.com
Ad