2

So far I know how to create a router model binding on single parameters like so:

// RouteServiceProvider.php
$router->model('subject_slug', 'App\Subject', function($slug) {
     return Subject::where('slug', $slug)->firstOrFail();
});

The above can then be used like this:

// routes.php
Route::get('/{subject_slug}', 'MenuController@showSubject');

And in the controller:

public function showSubject(Subject $subject) {
   ....
}

But sometimes I need to specify multiple parameters in order to get the right model.

For example consider the following route:

Route::get('/{subject_slug}/{topic_slug}/', 'MenuController@showTopic');

and the corresponding controller:

public function showTopic(Subject $subject, Topic $topic) {
   ....
}

However to get the correct model for Topic I need to know the Subject. For example:

// !!! Invalid laravel code !!!
$router->model('topic_slug', 'App\Topic, function($subject_slug, $topic_slug) {
     // ERROR: $subject_slug is obviously not defined!
     return Topic::where([
        'subject_slug' => $subject_slug,
        'slug' => $topic_slug,
     ])->firstOrFail();
});

How can I make a router model binding for Topic bearing in mind I need to know the Subject parameter before it in order to fetch the correct Topic.

Is there an alternative better way of doing this?

UPDATE

Currently my showTopic method in my controller is like this:

public function showTopic(Subject $subject, $topic_slug) {
   $topic = Topic::where([
               'subject_slug' => $subject_slug,
               'slug' => $topic_slug,
            ])->firstOrFail();
   // ...
}

and I have no router model binding for topic_slug. This works as expected, but I would like to take advantage of router model bindings!

2
  • 1
    I suspect there is no way of doing this, since what you're trying to do is, in effect, bind two models (Subject and Topic) to one route. You will probably have to fall back to good old route binding without the model binding to accomplish this. Commented Nov 24, 2015 at 14:27
  • Yeah that what i used. Didn't even know about bind Commented Nov 24, 2015 at 14:36

1 Answer 1

3

It turns out the way I was doing it was a bit flawed. I was unnessarily using model bindings when instead it would be better to have used a normal binding like so:

$router->bind('topic_slug', function($slug, Route $route) {
     $subject = $route->parameter('subject_slug');
     return Topic::where([
        'subject_slug' => $subject->slug,
        'slug' => $slug,
     ])->firstOrFail();
});

Also I was using model bindings completely wrong before as the 3rd function should be the "not found behaviour" (not for additional logic)!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.