How To Use Laravel Route Model Binding

Laravel has a bunch of features that makes development much easy. One of these features is Route Model binding so instead of using the primary key of the table to fetch the data of a single item we can take the advantage of route model binding as shown below.

 

Let’s demonstrate this with an example. Consider we have a posts table and we have a post model. To display the post by id we can do something like this:

// the route parameter is the id of the post
// for example http://example.com/posts/53
Route::get('posts/{id}', function ($id) {

    // we have to find the post using the $id
    $post = Post::find($id);

    // if there is no post, 404
    if (!$post) return abort(404);

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

In the code above first we query the post by id then check if its already exist finally we displayed the view.

To simplify things a bit more:

// the route parameter is the id of the post
// for example http://awesome.dev/posts/53
Route::get('posts/{id}', function ($id) {

    // find the post or 404 if not found
    $post = Post::findOrFail($id);

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

But with Route Model Binding we can simplify this as shown below:

// by using $post, we can inject the Post object
Route::get('posts/{post}', function ($post) {

    // we now have access to the $post object! no code necessary

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

So in the code above Laravel will inject a Post model into any route controller that has a {post} parameter attached to it.

 

Route Model Binding Types:

  • Implicit Model Binding
  • Explicit Model Binding

 

Implicit Model Binding:

Just typehint a parameter in the route Closure (or your controller method) and name the parameter the same thing as the route parameter, and it’ll automatically treat it as a route model binding.

Route::get('posts/{post}', function (App\Post $post) {
    // be awesome. enjoy having the $post object
});

Laravel is smart enough to know that since a Post model is being injected into the controller closure, it should get the id parameter from the route and get the details for the user.

Now you can access the post as http://example.com/posts/3

 

But what if you want to use a route key other than the id. You can do this through getRouteKeyName in the Eloquent model.

// here we used a slug instead of the 
// id in the route model binding

class Post extends Model {
    
    public function getRouteKeyName() {
        return 'slug';
    }
}

Then we could access our route using http://example.com/posts/my-post-slug instead of http://awesome.dev/posts/3.

 

Explicit Model Binding:

You have to explicitly tell laravel you want it to bind a url parameter to a particular model. There are two ways to do this, we could bind a parameter to a model using the provided Route facade or carry out this binding in app/Providers/RouteServiceProvider.php.

Using the Route Facade

Route::bind('post', 'App\Post');

Using the RouteServiceProvider

The only difference between using the Route facade and RouteServiceProvider class is that – registering your bindings is done in the boot method of the RouteServiceProvider class (location is app/Providers directory) and the bind method is called on the $router object injected into the method.

public function boot(Router $router)
{
    parent::boot($router);

    $router->bind('post', function ($value) {
        return App\Post::find($value)->where('status', '=', 'published')->first();
    });
}

 

Custom exceptions for route model binding

You can also customize the exceptions that the route model bindings throw (for example if they can’t find an instance of that model) by passing a Closure as the third parameter:

$router->model('posts', 'App\Post', function () {
    throw new NotFoundHttpException;
});

 

Conclusion

As you saw in this tutorial Route Model Binding saves you from writing a lot of code that that you repeat everyday  in actions that fetches a single records also it makes the code more readable and organized.

0 0 vote
Article Rating
Share this: