Laravel Resource Routes

Laravel Resource Routes

2020-05-30 Technology 0

And not just regular routes, but routes with modified resource names.

So, by default you create a standard resource route using a standard resource using the simple construct:

Route::resource('<route name>', '<controller class>');

e.g.:

Route::resource('configuration', 'ConfigurationController');

This will create a slew of default routes for the resource linked to the indicated controller. In the constructor of the controller, you can link authorization for these routes in an easy way as well:

public function __construct()
{
    $this->authorizeResource(Configuration::class, 'configuration');
}

This will automatically link your policies or gate definitions to the routes. What it actually does is add a middleware definition on-the-fly to the default resource routes using the ‘can:<ability>,<model>’ notation. It’s just a shortcut, but not defined in the routing section in web.php.

Now, what I normally like to do is name my model variables in a generic way. I mean, if I am inside my ConfigurationController, a variable named ‘model‘ is clear enough: it contains an instance of my Configuration model. However, Laravel links my route parameters to the controller method parameters, so if I have a show method like this:

public function show(Configuration $model, Request $request) {
    //
}

Then Laravel tries to find a route parameter named ‘model‘. In the default configuration specified above, the route parameter names are named after the singular version of the route, so you need to override this:

Route::resource('configuration', 'ConfigurationController')
    ->parameters(['configuration'=>'model']);

This will adjust the parameter name in your route and you can check this using artisan route:list. You need to match the left-hand part to the default name Laravel guesses for your resource route. And the right hand part of course matches the name of the controller method parameter.

But we’re not there yet. If you look closely at the route list created by artisan, you’ll notice that the authorization is still performed based on a parameter named ‘configuration‘:

web,auth,can:view,configuration

This is due to the authorizesRequest call in the constructor of the controller. You’ll need to match the route parameter name there explicitely:

public function __construct()
{
    $this->authorizeResource(Configuration::class, 'model');
}

When I write it down like this, it seems all very logical, but the error messages and debug information from Laravel are not helpful. You just get a 403 unauthorized and no hint as a developer as to why. It took me a few hours to wade through the various facades and contracts to see my errors.

 

Geef een reactie

Je e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *