Middleware SubstituteBindings
Middleware SubstituteBindings в Laravel выполняет автоматическую подстановку моделей Eloquent в методы контроллеров на основе параметров маршрута. Когда в определении маршрута используется параметр с указанием модели, этот middleware автоматически находит запись в базе данных и передаёт её в качестве аргумента в метод контроллера. Если запись не найдена, автоматически выбрасывается исключение ModelNotFoundException.
Синтаксис
<?php
// В файле маршрутов
Route::get('/users/{user}', [UserController::class, 'show']);
// В контроллере
public function show(User $user)
{
// Автоматически подставлена модель User с id из URL
return view('users.show', ['user' => $user]);
}
?>
Пример работы с моделью
Создадим маршрут для отображения статьи по идентификатору:
<?php
use AppHttpControllersArticleController;
use AppModelsArticle;
Route::get('/articles/{article}', [ArticleController::class, 'show']);
?>
Теперь создадим контроллер с методом show, который принимает модель Article:
<?php
namespace AppHttpControllers;
use AppModelsArticle;
class ArticleController extends Controller
{
public function show(Article $article)
{
echo "Article title: " . $article->title;
echo "Article text: " . $article->text;
return $article;
}
}
?>
При обращении к маршруту /articles/1 результат будет следующим:
"Article title: First article"
"Article text: Content of first article"
Пример с несколькими моделями
SubstituteBindings поддерживает подстановку нескольких моделей в одном маршруте:
<?php
use AppHttpControllersPostController;
use AppModelsUser;
use AppModelsPost;
Route::get('/users/{user}/posts/{post}', [PostController::class, 'show']);
?>
<?php
namespace AppHttpControllers;
use AppModelsUser;
use AppModelsPost;
class PostController extends Controller
{
public function show(User $user, Post $post)
{
echo "User: " . $user->name;
echo "Post: " . $post->title;
return [$user, $post];
}
}
?>
При обращении к маршруту /users/1/posts/5 будут автоматически найдены обе модели:
"User: John Doe"
"Post: Laravel Middleware Guide"
Пример с кастомным ключом
По умолчанию поиск выполняется по полю id. Можно указать другое поле для поиска с помощью метода routeKeyName в модели:
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
class Article extends Model
{
public function getRouteKeyName()
{
return 'slug';
}
}
?>
Теперь маршрут будет искать статьи по полю slug:
<?php
use AppHttpControllersArticleController;
use AppModelsArticle;
Route::get('/articles/{article}', [ArticleController::class, 'show']);
?>
<?php
namespace AppHttpControllers;
use AppModelsArticle;
class ArticleController extends Controller
{
public function show(Article $article)
{
echo "Article: " . $article->title;
return $article;
}
}
?>
При обращении к маршруту /articles/laravel-guide будет найдена статья с соответствующим значением в поле slug:
"Article: Laravel Middleware Guide"
Смотрите также
-
метод
where,
который ограничивает параметры маршрута регулярными выражениями -
метод
scopeBindings,
который обеспечивает связывание дочерних моделей через родительские -
метод
bind,
который выполняет явную привязку параметров маршрута -
класс
SubstituteBindings,
который реализует автоматическую подстановку моделей