Cleaner Laravel Controllers with Route Model Binding

Laravel as a framework either for building websites or a container to build APIs (lumen) has evolved as a developers framework of choice. Laravel comes with a lot of growing features - take for example Laravel's events. Events in Laravel used to be a simple pub-sub library, but now Laravel events can broadcast all the way to the client and allows us to [create realtime apps]https://scotch.io/tutorials/create-a-real-time-shoutbox-with-laravel-events).

But that's beside the point, today's celebrity is Laravel's route model binding.

What is Route Model Binding

Route model binding in Laravel provides a mechanism to inject a model instance into your routes. Still not clear on the meaning, here is an example. Say we want to get a post from the database, we could 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'));
});
...

We could further go on to simplify this method into

...
// 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 route model binding helps us get rid of extra keystrokes by simplifying both instances above into

...
// 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'));
});
...

This is made possible by telling Laravel to inject a Post model into any route controller that has a {post} parameter attached to it.

Laravel currently supports two types of route model bindings. We have:

  • Implicit model binding
  • explicit model binding

NOTE: The example of route model binding listed above is explicit.

Implicit Model Binding

While we've seen explicit model binding, here's an example of implicit model binding now:

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.

Accessing a post will still be done using http://awesome.dev/posts/24.

Changing the Model's Route Key

...

read more @ Scotch