Route Model Binding in Lravel 5

Suppose we have multiple routes with same patterns for example each route accepts userId wild card key. We usually end up writing code for fetching user information in both routes, this code will explain what I am trying to say.

<?php

//We are getting user id and showing all information of that user
Route::get('users/{userId}',  function($userId)
{
	//Fetching user information
    //Returning user Information
});

//Again We are getting user id and showing all articles of that user
Route::get('users/{userID}/articles', function($userId) 
{
    //Fetching user Information
    //Getting Articles for that user
    //Returning Articles for that user

});

 

In both routes we are fetching user information and we end up writing same code for fetching query multiple times, we need some kind of mechanism to get data without writing code multiple times.

Laravel route model binding is quite handy feature for this, once we bind wild card key to specific model, we will get model instance for that id.   

We need to tell laravel that we need binding for specific wild card, open app/Providers/RouteServiceProvider.php  and specify your binding in boot method.

<?php

public function boot(Router $router)
{
    parent::boot($router);
    
   //Add your binding

    $router->model('userId', 'App\User'); // this will return instance of User Class for given ID

   // In some cases userId is not valid and we don't get Any instance for that to be fail safe we    // can throw exception as third parameter 
   // This is optional

    $router->model('userId', 'App\User', function() {

         throw new NotFoundHttpException;
    
    });
  
}

 

In routes.php, we will now get instance of User class for that id in Closure( Anonymous ) or if we are using controllers Instance will be passed to associated method. 

<?php

Route::get('users/{userId}',  function(User $user){
	
    //We have Associated user, there is no need to run query
    return $user;

});

 

Above will work fine with id but in complex application we need much more logic in query such as find user by using first_name, email etc, for that we can use bind( instead of model) in boot method.

<?php

public function boot(Router $router)
{
    parent::boot($router);
    
    $router->bind('userEmail', function($email) {

         return \App\User::where('email', $email)->first();
    
    });
  
}

 

Now associated routes will get User class instance for that email. Route model binding is great feature to use in small scale applications, remember you are not reducing number of running queries, its just you are not running them in controllers.

 

Something to say? Tell us in comment section.