Route Model Implicit and Explicit Binding in Laravel

Published on July 1, 2020 1 min read

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. ­čÖé

Monthly Newsletter

One email a month, packed with the latest tutorials, delivered straight to your inbox.
We'll never send any spam or promotional emails.
Author

Hey, I'm Md Obydullah. I build open-source projects and write on Laravel, Linux server, modern JavaScript and more on web development. If you enjoy my content, please consider supporting what I do!

Follow Buy me a coffeeBuy me a coffee

Leave a Reply

Your email address will not be published. Required fields are marked *