Route Model Binding
Route Model Binding — это механизм, при котором Laravel автоматически подставляет модель вместо ID из URL. Не нужно писать Post::findOrFail($id) — фреймворк делает это сам.
Неявный binding
Если в аргументе метода указан тип модели с именем, совпадающим с параметром роута:
Route::get('/posts/{post}', function (App\Models\Post $post) {
return $post->title;
});
Laravel:
- Видит параметр
{post} - Видит тип
Postв аргументе - Ищет
Post::findOrFail($id) - Передаёт модель в функцию
Если запись не найдена — 404.
В контроллере
public function show(Post $post)
{
return view('posts.show', compact('post'));
}
Binding по slug
По умолчанию ищется по id. Если нужен другой столбец — переопредели getRouteKeyName:
class Post extends Model
{
public function getRouteKeyName(): string
{
return 'slug';
}
}
Теперь /posts/hello-world найдёт пост с slug = hello-world.
Явное указание ключа в роуте
Route::get('/posts/{post:slug}', function (Post $post) {
return $post;
});
Не требует менять модель.
Составные ключи
Если нужно искать по двум полям:
public function resolveRouteBinding($value, $field = null)
{
return $this->where('slug', $value)
->where('published', true)
->firstOrFail();
}
Кастомизация
Можно задать свою логику:
Route::bind('post', function ($value) {
return Post::where('slug', $value)->firstOrFail();
});
Вложенный binding
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
// Laravel найдёт и user, и post
});
Если нужно, чтобы пост принадлежал пользователю — используй scoped bindings:
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
//
})->scopeBindings();
Теперь post ищется среди постов пользователя.