6

Is it possible to have route model binding using multiple parameters? For example

Web Routes:

Route::get('{color}/{slug}','Products@page');

So url www.mysite.com/blue/shoe will be binded to shoe Model, which has color blue.

Fusion
  • 5,046
  • 5
  • 42
  • 51

3 Answers3

14

First of all, it would feel more natural to have a route like the following:

Route::get('{product}/{color}', 'Products@page');

and to resolve product by route binding, and just use the color parameter in the controller method directly, to fetch a list of blue shoes for example.

But let's assume that for some reason it's a requirement. I'd make your route a bit more explicit, to start with:

Route::get('{color}/{product}', 'Products@page');

Then, in the boot method of RouteServiceProvider.php, I would add something like this:

Route::bind('product', function ($slug, $route) {
    $color = $route->parameter('color');

    return Product::where([
        'slug'  => $slug,
        'color' => $color,
    ])->first() ?? abort(404);
});

first here is important, because when resolving route models like that you effectively want to return a single model.

That's why I think it doesn't make much sense, since what you want is probably a list of products of a specific color, not just a single one.

Anyways, I ended up on this question while looking for a way to achieve what I demonstrated above, so hopefully it will help someone else.

osteel
  • 588
  • 4
  • 13
  • This answers the question. However, I am kind a puzzled, why you dont use firstOrFail() method instead of abort(404)? – Fusion Dec 29 '17 at 11:19
  • @Fusion that’s the way it is handled in the official doc, I assume `abort(404)` returns a proper 404 response. Would need to check what `findOrFail` does exactly, not sure the response would be the same – osteel Dec 31 '17 at 11:05
  • @Fusion just realised you meant `firstOrFail`. Does that method even exist? (Can’t check right now) – osteel Dec 31 '17 at 11:10
  • both findOrFail() and firstOrFail() exist. I preffer using firstOrFail() looks like they do the same thing. – Fusion Dec 31 '17 at 17:43
  • @Fusion cool. Don’t forget to accept my answer if you think it addresses your question correctly – osteel Jan 01 '18 at 18:17
0

Do not forget to declare the parameter types:

Route::delete('safedetail/{safeId}/{slug}', [
    'as' => 'safedetail.delete',
    'uses' => 'SafeDetailController@destroy',
])->where([
    'safeId' => '[0-9]+',
    'slug' => '[a-z]+',
]);
Sinan Eldem
  • 5,564
  • 3
  • 36
  • 37
-2

Try changing your controller to this:

class Pages extends Controller{

    public function single($lang, App\Page $page){

        dd($page);

    }

}

You must add the Page Model.

Robin
  • 1,567
  • 3
  • 25
  • 67