Learn Laravel – Route Model Binding

Laravel

There is a feature in laravel which allows you to inject into the route model instances. Previously, you would have had to pass the ID of the model that you wanted to work with in the request and then you would write all the business logic yourself and validate the Models ID.

api/posts/{post_id}

With laravel we can pass through the entire model instance that matches the given ID in the URL. There are two methods with route model binding: Implicit Model Binding and Explicity Model Binding.

Implicit Model Binding

With this approach, you’ll directly inject the model instance into the route or controller actions. Laravel is smart enough to know that the post model is being injected into the controller closure and that it should retrieve the post by it’s ID parameter.

Route::get('posts/{post}', function (App\Post $post) {
  // 
});

You can also tell laravel that you wish to use the implicit model binding to use a different column from the database, other than ID when retrieving the models. To do this you will need to override the getRouteKeyName method in your eloquent model.

For instance if we wanted to use slug instead of id, we can do the following:

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

We will then access our route using api/posts/{slug}.

Explicit Model Binding

You can explicitly tell laravel that you want to bind a url parameter to a particular model. You can bind a parameter using the route facade or by altering the code in the app/Providers/RouteServiceProvider.php.

Route Facade

Using the route facade to bind the parameter to a model, we can do the following:

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

We can give the binding more meaning. Say we wanted to only return posts that are published:

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

Using the RouteServiceProvider

The only difference between the route facade and the RouteServiceProvider class is the registering of the bindings is done in the boot method in the RouteServiceProvider class, where 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();
  });
}

This is a realy neat feature and you can learn more about route model binding in the laravel documentation.

Leave a Reply

Your email address will not be published.