Route Model binding in Laravel

Ep#23@Laracasts: Route Model Binding

This post is a part of the Week X of 100DaysOfCode Laravel Challenge series.

What is Route-Model Binding?

As the name tells, to bind an Eloquent Model instance to a route (wildcard).

At this point in our Blog Project, we capture the post ID in the route definition for a single post, pass it to the callback function as paramere, and then send it to the findOrFail() method of our Post model.

Route::get('/posts/{post}', function ($id) {
    return view('post', [
        'post' => Post::findOrFail($id)
    ]);
});

Would it not be nicer to send the Post model instance directly to the callback function?

Route::get('/posts/{post}', function (Post $post) {
    return view('post', [
        'post' => $post
    ]);
});

It means we bound the Post model to the route /posts/{post}.

Things to remember about the Route-Model Binding:

  1. The Model type-hinted variable name in the route callback function should be the same as the route wildcard name. It means if your wildcard is {post} then callback variable name must be $post, otherwise it would not work.

  2. The default key that represents a Model is ID. It means, Laravel by default will assume the wildcard value to be the ID attribute of the Model instance. You can change it to any other unique key in the following two ways:

a) Update your route definition to mention the key with the wildcard as {post:slug}.

Route::get('/posts/{post:slug}', function (Post $post) {
    return view('post', [
        'post' => $post
    ]);
});

This is a relatively newer approach introduced in some recent version of Laravel.

b) Add a public function to your Model getRouteKeyName() and return the field name from it.

public function getRouteKeyName() {
    return 'slug';
}

This was the old way of changing the default key which still works.

Update you view files accordingly based on what key represents your Model. For example, if you changed it from id to slug, update your posts.blade.php as in the image

24