Home » Php » php – Laravel nested route model binding

php – Laravel nested route model binding

Posted by: admin July 12, 2020 Leave a comment


I am developing an API using Laravel for use with a mobile app and am having some issues with Route Model Binding on nested routes.
The app will have a standalone sqlite db which will synchronise client journeys with the central server when network is available. For that reason, the PK’s in the app cannot be used to access the records on the central server. Each user will have a unique username which will be stored on the central server in a table with the following columns:

  • user_id
  • username

The journey table will then have the following columns:

  • journey_id
  • user_id
  • user_journey_id

where the user_journey_id will be the PK of the journey record on the client device.
The idea is that the clients can then access the api with something like:
to retrieve the journey from the central server.

I have the following resources setup:


and have setup route model binding successfully for the client as follows:

$router->bind('client', function($value, $route) {
    return \App\Client::where('username', '=', $value)->firstOrFail();

I’m having a bit of trouble with setting up the nested model binding as I require the client username in combination with the user_journey_id to retrieve the correct journey. Is there a way to do this with route model binding?
Or should this just be done in the controller with some like:

public function show(Client $client, $user_journey_id)
   ... // have logic here to get the journey.

This is how I do it currently but the route model binding would certainly make it a bit easier.

How to&Answers:

Binding multiple URL parameters to models is certainly possible in Laravel, as is nested route model binding.

One caveat is that you’ll need to specify the routes individually for these particular routes, rather than using Laravel’s resource controllers as you’ve used in your example.

To register a route with more than one model binding you’ll need to do something like this:

The route definition:

Route::get('/api/client/{user}/journey/{journey}', [
  'as' => 'client.journey', 
  'uses' => '[email protected]'

The bind definitions:

$router->bind('user', function($value, $route) {
    return \App\Client::where('username', '=', $value)->firstOrFail();

$router->bind('journey', function($value, $route) {
    return \App\Journey::where('user_journey_id', '=', $value)->firstOrFail();

You’ll then find that both models are being resolved and injected to the action method in the controller class:

public function show(User $user, Journey $journey)
     //do whatever you need to do here...

The only real drawback to this approach is the fact that you have to define routes manually instead of making use of Laravel’s handy resource controllers. Of course, you could implement some of your own logical to make these kinds of routes easier for you to define.


I think your approach is not good and you’ll end anyways using a separate controller for this, as you probably need to add an auth layer in the future or a more functionality.

Having the username is the URL is not good either as it can be a string with special characters that will be URL encoded, then decoded, so prone to errors. I’d suggest to using the ids as it’s an API.

Resources will call a specific method for each requested action, I’d recommend using those methods.