Для тех, кто не знает, привязка модели маршрута уже давно есть в Laravel, но в Laravel 5.2 она стала ещё проще.
Это одна из статей о новых функциях Laravel 5.2. Скоро будут ещё, не пропустите.
- Проверка массива формы в Laravel 5.2
- Неявная привязка модели маршрута в Laravel 5.2
- Ограничение скорости запросов API в Laravel 5.2
- Заготовка авторизации в Laravel 5.2
- Множественные драйверы защиты авторизации (включая API) в Laravel 5.2
Основы привязки модели маршрута
Предположим, что обычный шаблон для привязки URL-маршрута выглядит примерно так:
Route::get('shoes/{id}', function ($id) {
$shoe = Shoe::findOrFail($id);
// Делаем, что нам надо
});
И такое мне приходится делать часто. Разве не было бы лучше, если бы можно было написать PHPfindOrFail
и просто сказать маршрутизатору Laravel, что этот маршрут соответствует PHPShoe
? Это возможно. Просто скажите маршрутизатору в своём сервис-провайдере маршрута:
$router->model('shoe', 'App\Shoe');
Это значит, что «каждый раз, когда в маршруте есть параметр с именем PHPshoe
, это ID соответствующий экземляру PHPApp\Shoe
». Тогда мы можем переписать этот код вот так:
Route::get('shoes/{shoe}', function ($shoe) {
// Делаем, что нам надо
});
Неявная привязка модели маршрута
В Laravel 5.2 ещё проще использовать привязку модели маршрута. Просто укажите тип параметра в замыкании маршрута (или методе своего контроллера) и назовите параметр также, как параметр маршрута, тогда он автоматически будет обработан как привязка модели маршрута:
Route::get('shoes/{shoe}', function (App\Shoe $shoe) {
// Делаем, что нам надо
});
Значит теперь вы можете использовать преимущества привязки модели маршрута без необходимости определять что-либо в сервис-провайдере маршрута. Легко!
Это всё, что касается неявной привязки модели маршрута! А всё остальное уже было в 5.1.
Малоизвестные возможности привязки модели маршрута
Эти возможности появились до версии 5.2, поэтому они не связаны конкретно с неявной привязкой модели маршрута, но судя по всему они малоизвестны, так что сейчас я расскажу о них.
Настройка логики привязки модели маршрута
Если вы хотите изменить логику, которую использует привязка модели маршрута для поиска и возврата экземпляра вашей модели, вы можете передать замыкание в качестве второго параметра явной привязки вместо передачи имени класса:
$router->bind('shoe', function ($value) {
return App\Shoe::where('slug', $value)->where('status', 'public')->first();
});
Настройка исключений привязки модели маршрута
Также вы можете изменить исключения, которые выбрасывают привязки моделей маршрутов (когда они не могут найти экземпляр модели), передав замыкание в качестве третьего параметра:
$router->model('user', 'App\User', function () {
throw new NotFoundHttpException;
});
Изменение «ключа маршрута» модели Eloquent
По умолчанию Laravel предполагает, что модель Eloquent должна направлять к сегментам URL по столбцу id. Но что если вы хотите, чтобы она всегда направляла к «читаемому» адресу, как в моем примере с изменённой логикой привязки PHPshoe
?
Eloquent реализует контракт Illuminate\Contracts\Routing\UrlRoutable, значит каждый объект Eloquent имеет метод PHPgetRouteKeyName()
, который определяет, какое поле надо использовать для поиска этого объекта по URL. По умолчанию оно равно PHPid
, но вы можете переопределить его для каждой модели PHPEloquent
:
class Shoe extends Model
{
public function getRouteKeyName()
{
return 'slug';
}
}
Теперь вы можете использовать явную или неявную привязку модели маршрута, и она будет искать тот shoe, в котором поле slug совпадает с сегментом моего URL. Красота.
Комментарии (2)
а где это может пригодиться?
там где у модели Shoe мб несколько состояний (status —>public | status->hidden(?))
хотя мне больше нравится вариант, active->true | active->false