Mr.Singh
Mr.Singh

Reputation: 1781

Laravel: Resource Controller change parameter from ID to Slug

In my Laravel application I was using the normal routes, such as GET, POST, PUT and all with the various controllers. But as the application progresses, the routes/api.php file is turning out quite bulky. So, I am changing it with the "Resource Controller" syntax, for cleaner and reduced code.

However, earlier I was able to use the "token" or "slug" parameters in the url to fetch the data, for example: show/{token} & show($token) or show/{slug} & show($slug), but now whenever I try these or any other parameter I get 404 not found error. Therefore I am stuck with the default "id" parameter only.

Earlier:

Route::get('/categories', 'CategoryController@index');
Route::get('/categories/{token}', 'CategoryController@show');

Now:

Route::resource('/categories', 'CategoryController');

Is there any way to change the default "id" parameter to any other ..?

Upvotes: 9

Views: 17793

Answers (2)

glupeksha
glupeksha

Reputation: 520

This can also be achieved by changing the customizing the key. In here slug refers to a column in the Category model.

Route::resource('categories', 'CategoryController')->parameters([
    'categories' => 'category:slug',
]);

Please note:

In the call to parameters above, the key categories should match the name used in the resource route: Route::resource('categories',....

The value, 'category:slug', should match the name used in the method signature of the controller, eg: public function edit(Category $category), combined with the name of the key you wish to use on the Category model.

Upvotes: 15

lagbox
lagbox

Reputation: 50491

For Resource Routing the route parameter is the resource name, first argument, in singular form.

Route::resource('categories', 'CategoryController');

Will give you a route parameter of category. You can see this by running php artisan route:list and looking at the routes that are defined.

If you want to use a different parameter name for a resource you can also do that by overriding the parameter:

Route::resource('categories', 'CategoryController')->parameters([
    'categories' => 'something',
]);

Now the route parameter used would be something.

This only has to do with the route parameter name, it has nothing to do with how any binding would be resolved, unless you had an Explicit Route Model Binding defined specifically for a parameter name.

If you are using Implicit Route Model Bindings you would define on your Model itself what field is used for the binding via the getRouteKeyName method. [In the next version of Laravel you will be able to define the field used in the route definition itself.]

Laravel 6.x Docs - Controllers - Resource Controllers - Naming Resource Parameters

Laravel 6.x Docs - Routing - Model Bindings - Implicit Route Model Binding getRouteKeyName

Upvotes: 15

Related Questions