Paulund
2017-08-28 #laravel

Laravel Route Model Binding

This is one of my favourite features of Laravel routing and one of the features I see most underused, it's the model binding on the router. Let's think about the standard route you will create for say a User model. You'll have the standard crud routes in your application index, create, show, update and delete. The routes in your web.php routes file will look similar to below, using the ID of the user in the route so that we can collect the user model in the controller.


// Users
Route::group(['prefix' => 'user'], function(){
    Route::get('/', 'UserController@index');
    Route::get('/create', 'UserController@create');
    Route::post('/store', 'UserController@store');
    Route::get('/{id}', 'UserController@show');
    Route::patch('/{id}', 'UserController@update');
    Route::delete('/{id}', 'UserController@delete');
});

In the controller of the show method we want to get the ID from the route, search the database for the user, if the user doesn't exist throw a 404 error, if the user does exist return the user model to the view. It will look something like below.


public function show($id)
{      
    $user = User:findOrFail($id);

    return view('user.show', compact('user'));
}

Using Laravel implicit binding there is a better way to handle this sort of request. Instead of telling the router we're going to use an ID we can instead tell it we're going to use a user.


// Users
Route::group(['prefix' => 'user'], function(){
    Route::get('/', 'UserController@index');
    Route::get('/create', 'UserController@create');
    Route::post('/store', 'UserController@store');
    Route::get('/{user}', 'UserController@show');
    Route::patch('/{user}', 'UserController@update');
    Route::delete('/{user}', 'UserController@delete');
});

Then in the controller show method we can type-hint the user model to the {user} parameter and Laravel will automatically lookup the User model using the primary key of the model and the parameter passed in the router. Now our show method looks like this.


public function show(User $user)
{      
    return view('user.show', compact('user'));
}