
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.