Reputation: 2454
When you define a resource with Route::resource('recipe', 'RecipeController');
, among others, the following route is defined: /photo/{photo}/edit
, and once you define all your resources you have something like this:
/recipes/{recipes}/edit
/allergens/{allergens}/edit
/ingredients/{ingredients}/edit
Because all my records use id
as primary key (MongoDB), I'd like to have {id}
instead, like so:
/recipes/{id}/edit
/allergens/{id}/edit
/ingredients/{id}/edit
I dug in the Router
class but I don't see how to specify this.
More over when I create a form with Form::model($record)
I get actions like /recipes/{recipes}
because recipes
is a property of $record
.
How can I define the name of the key parameter to id
instead of recipes
, allergens
, ingredients
?
Upvotes: 7
Views: 5403
Reputation: 1140
I know this is 4 year old question but for anyone who is googling; you can pass a third argument to override key naming:
Route::resource('ingredients', 'IngredientController', ['parameters' => ['ingredients' => 'id']]);
Or
Route::resource('ingredients', 'IngredientController')->parameters(['ingredients' => 'id']);
Upvotes: 8
Reputation: 81167
In order to change the param name for Route::resource
, you need custom ResourceRegistrar
implementation.
Here's how you can achieve that in a shortest possible way:
// AppServiceProvider (or anywhere you like)
public function register()
{
$this->app->bind('Illuminate\Routing\ResourceRegistrar', function ($app) {
// *php7* anonymous class for brevity,
// feel free to create ordinary `ResourceRegistrar` class instead
return new class($app['router']) extends \Illuminate\Routing\ResourceRegistrar
{
public function register($name, $controller, array $options = [])
{
if (str_contains($name, '/')) {
return parent::register($name, $controller, $options);
}
// ---------------------------------
// this is the part that we override
$base = array_get($options, 'param', $this->getResourceWildcard(last(explode('.', $name))));
// ---------------------------------
$defaults = $this->resourceDefaults;
foreach ($this->getResourceMethods($defaults, $options) as $m) {
$this->{'addResource'.ucfirst($m)}($name, $base, $controller, $options);
}
}
};
});
}
Now your routes will look like:
Route::resource('users', 'UsersController', ['param' => 'some_param'])
/users/{some_param}
// default as fallback
Route::resource('users', 'UsersController')
/users/{users}
Mind that this way can't work for nested resources and thus they will be a mix of default and custom behaviour, like this:
Route::resource('users.posts', 'SomeController', ['param' => 'id'])
/users/{users}/posts/{id}
Upvotes: 4
Reputation: 7381
You can pass your ids to the routes you don't necessary need to change the parameters {recipes} to {id} since the parameters are just a placeholder.
So
public function edit($recipes){
// code goes hr
}
is the same as this
public function edit($id){
// code goes hr
}
for this route /recipes/{recipes}/edit
Upvotes: 0