Menu

Route Model Binding

I really love in Laravel how it tries to make our development process enjoyable and easier. I think Taylor Ottwell did a great job in this aspect too.

Route-model binding is one of these great features. So let’s see how it makes our life a bit easier. Let’s assume we have some kind of user resource and we’re referencing to it in our routes file:

Route::resource('users', 'UsersController');

Without binding our model to a specific route, we have to hunt down the current resource and pass it to our blade template manually. It’s still not the wort thing ever, but after a few project is can be boring. So our show method in the UsersController should look like this.

/**
 * Display the specified resource.
 *
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function show($id)
{
    $user = User::findOrFail($id);

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

If we navigate to app/Providers/RouteServiceProvider.php, in the boot method we have to bind our model to the route paramater. It’s gonna be one line of code and it can save us a lot of time.

/**
     * Define your route model bindings, pattern filters, etc.
     *
     * @param  \Illuminate\Routing\Router  $router
     * @return void
     */
    public function boot(Router $router)
    {
        $router->model('users', \App\User::class);
        
        parent::boot($router);
    }

Why ‘users’? In the routes file, we give a Route::resource(‘users’, …), which means, our show route should look something like this: /users/{users}. For posts it should be /posts/{posts} etc. So we have to reference the route parameter between the braces. In our case it’s ‘users’.

Of course we can do this many times, bind any kind of eloquent model to any kind of route parameter. There are a lot of flexibility, it’s brilliant. Now in our controller, we can edit the show method.

/**
 * Display the specified resource.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \App\User  $user
 * @return \Illuminate\Http\Response
 */
public function show(Request $request, User $user)
{
    return view('user.show', compact('user'));
}

Laravel is smart enough to hunt down the target resource by the id and fetches it behind the scenes.

With Laravel 5.2, implicit route-model binding is shipped out of the box. We can do the following in our routes file:

Route::get('users/{user}', function (App\User $user) {
    return $user;
});

And thats it. If the requested resource is not found in the database, Laravel will fetch and empty instance of the model.

Laracasts episodes: https://laracasts.com/lessons/route-model-bindinghttps://laracasts.com/series/whats-new-in-laravel-5-2/episodes/1
Documentation and resources: https://laravel.com/docs/5.2/routing#route-model-binding

Have something on your mind?