Иногда бывает необходимо добавить свои данные к текущему запросу в Laravel. Например, вы помещаете в мидлвар проверку, разрешен ли пользователю доступ к этой странице, и, затем, передаете эту «проверку» дополнительным параметром текущего запроса.
Таким образом, вы предотвращаете дублирование кода, не размещая один и тот же код (или запрос) в мидлваре и контроллере. Например, возьмем следующую ситуацию: я хочу дать доступ только пользователям, у которых is_active
установлен в «1
», соответственно, мне нужно дважды сделать следующий запрос.
SomeUserMiddleware.php
public function handle($request, Closure $next)
{
// получаем ID пользователя
$userId = $request->route('id');
// находим пользователя
$user = User::where('is_active', 1)->where('id', $userId)->first();
// проверяем, существует ли залогиненный пользователь
if (!$user->exists()) {
// редиректим, если не существует
return redirect()->route('redirectRoute');
}
return $next($request);
}
UserController.php
public function view($id)
{
$user = User::where('is_active', 1)->where('id', $userId)->first();
return view('users.view', ['page' => $user]);
}
Как вы видите, запрос на получение пользователя сделан дважды. Пустая трата ресурсов, не так ли?
Можно отрефакторить приведенный выше код, вызвав метод merge
в запросе и передав $user
из мидлвара следующим образом.
SomeUserMiddleware.php
public function handle($request, Closure $next)
{
//получаем ID пользователя
$userId = $request->route('id');
//находим пользователя
$user = User::where('is_active', 1)->where('id', $userId)->first();
// проверяем, существует ли залогиненный пользователь
if (!$user->exists()) {
// редиректим, если не существует
return redirect()->route('redirectRoute');
}
// передаем атрибут в запрос
$request->merge(['user' => $user]);
return $next($request);
}
И получаем в контроллере, например так:
UserController.php
public function view($id)
{
return view('users.view', ['user' => $request->user]);
}
Преимущество вышеизложенного способа заключается в том, что теперь нам нужно выполнить только одно обращение к базе данных и передать его результат в запрос, который можно будет повторно использовать в другом месте (в нашем случае, в контроллере). И, как дополнительный бонус, мы делаем наши контроллеры «тонкими»!