Добавление данных в текущий запрос

Request merge data

Иногда бывает необходимо добавить свои данные к текущему запросу в 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

Можно отрефакторить приведенный выше код, вызвав метод 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]);
}

Преимущество вышеизложенного способа заключается в том, что теперь нам нужно выполнить только одно обращение к базе данных и передать его результат в запрос, который можно будет повторно использовать в другом месте (в нашем случае, в контроллере). И, как дополнительный бонус, мы делаем наши контроллеры «тонкими»!

Автор: Amit Merchant
Перевод: Алексей Широков

Наш Телеграм-канал — следите за новостями о Laravel.