Route Model Implicit and Explicit Binding in Laravel

Laravel provides a mechanism to inject a model instance into your routes. It is called Route model binding. It’s a new feature. I’m testing on Laravel 7.

Table of Contents

  1. Route Model Binding
  2. Implicit Model Binding
  3. Explicit Model Binding

Route Model Binding

Let’s see an example: To get a post from the database, we could do something like this in route:

Route::get('posts/{id}', function ($id) {

    // find the post or return 404 response
    $post = Post::findOrFail($id);

    // return view with post
    return view('post.show', compact('post'));
});

But route model binding simplifies extra coding. We can write the above code using binding like this:

Route::get('posts/{post}', function ($post) {

    // example: posts/101
    // return the post 101

    // return the view and the post
    return view('post.show', compact('post'));
});

Implicit Model Binding

Here’s an example of implicit model binding:

Route::get('posts/{post}', function ($post) {
    // return the post
});

It takes id parameter from. So the URL looks like: http://laravel.test/posts/101.

Change Default Key: By default it takes id. We can change it to any key. Let’s change it to slug. Using getRouteKeyName method, we can change the key. Open Post model and add the method like:

class Post extends Model
{
    /**
     * Get the route key for the model.
     *
     * @return string
     */
    public function getRouteKeyName()
    {
        return 'slug';
    }
}

Now we can access the post using http://laravel.test/posts/post-slug-101. We can also change key like:

Route::get('posts/{post:id}', function ($post) {
    // return the post using id
});

Route::get('posts/{post:slug}', function ($post) {
    // return the post using slug
});

Explicit Model Binding

To register an explicit binding, use the router’s model method to specify the class for a given parameter. You should define your explicit model bindings in the boot method of the app/Providers/RouteServiceProvider.php class:

public function boot()
{
    parent::boot();

    Route::model('user', App\User::class);
}

Next, define a route that contains a {user} parameter:

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

Now we can send request like /profile/1. It’ll retrieve user’s 1 data.

Customize Resolution Logic: We can apply our own resolution logic. Here’s an example:

public function boot()
{
    parent::boot();

    Route::bind('user', function ($value) {
        return App\User::where('name', $value)->firstOrFail();
    });
}

That’s it. Thanks for reading.


Software Engineer | Ethical Hacker & Cybersecurity...

Md Obydullah is a software engineer and full stack developer specialist at Laravel, Django, Vue.js, Node.js, Android, Linux Server, and Ethichal Hacking.