If you've never used it, Laravel's route model binding has been around for a while, but Laravel 5.2 is about to make it even easier.
The basics of route model binding #
Let's assume that a common pattern for binding a URL route is something like this:
Route::get('shoes/{id}', function ($id) {
$shoe = Shoe::findOrFail($id);
// Do stuff
});
This is something I do a lot. Wouldn't it be nice if you could drop the
findOrFail
line and just teach Laravel's router that this route represents a Shoe? You can. In your route service provider, just teach the router: $router->model('shoe', 'App\Shoe');
That means, "any time I have a route parameter named shoe
, it's an ID representing an instance of App\Shoe
". This allows us to re-write the above code like this:Route::get('shoes/{shoe}', function ($shoe) {
// Do stuff
});
Implicit route model binding #
In Laravel 5.2, it's even easier to use route 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('shoes/{shoe}', function (App\Shoe $shoe) {
// Do stuff
});
That means you can now get the benefits of route model binding without having to define anything in the Route Service Provider. Easy!
That's it for implicit route model binding! Everything past this point is already around in 5.1.
Little known features of route model binding #
These features are not new with 5.2, and therefore not specific to implicit route model binding, but they seem to be not commonly known, so I thought I would throw them in here.
Custom binding logic for route model binding #
If you want to customize the logic a route model binding uses to look up and return an instance of your model, you can pass a Closure as the second parameter of an explicit bind instead of passing a class name:
$router->bind('shoe', function ($value) {
return App\Shoe::where('slug', $value)->where('status', 'public')->first();
});
Custom exceptions for route model binding #
You can also customize the exceptions that the route model bindings throw (if they can't find an instance of that model) by passing a Closure as the third parameter:
$router->model('user', 'App\User', function () {
throw new NotFoundHttpException;
});
Changing an Eloquent model's "route key" #
By default, Laravel assumes an Eloquent model should map to URL segments using its
id
column. But what if you expect it to always map to a slug, like in my shoe custom binding logic example above?
Eloquent implements the
Illuminate\Contracts\Routing\UrlRoutable
contract, which means every Eloquent object has a getRouteKeyName()
method on it that defines which column should be used to look it up from a URL. By default this is set to id
, but you can override that on any Eloquent model:class Shoe extends Model
{
public function getRouteKeyName()
{
return 'slug';
}
}
Now, I can use explicit or implicit route model binding, and it will look up shoes where the
slug
column is equal to my URL segment. Beautiful.from : https://mattstauffer.co/blog/implicit-model-binding-in-laravel-5-2
沒有留言:
張貼留言