Сделать действие необязательным для страницы сведений о ресурсе - PullRequest
0 голосов
/ 18 января 2019

Допустим, у меня есть действие "Ban" для ресурса Product, а модель Product имеет поле is_banned. Нет необходимости показывать действие «Ban» на странице сведений о Product, которая уже забанена (is_banned=1).

В документации Laravel Nova приведен пример сокрытия действий, основанных на том, имеет ли администратор полномочия на их выполнение:

public function actions(Request $request)
{
    return [
        (new Actions\EmailAccountProfile)->canSee(function ($request) {
            return $request->user()->can(
                'emailAnyAccountProfile', User::class
            );
        }),
    ];
}

Но это не касается того, как я могу получить экземпляр модели текущего ресурса в замыкании, которое я предоставляю для разрешения canSee, когда этот метод вызывается в контексте одного ресурса (на странице сведений о нем).

actions() метод, в котором мы регистрируем доступные действия, и в моем случае он относится к Product классу ресурсов Nova, но он также не имеет доступа к контексту модели Eloquent.

Как этого достичь?

1 Ответ

0 голосов
/ 18 января 2019

После некоторой отладки я обнаружил, что метод actions() ресурса получает Laravel\Nova\Http\Requests\NovaRequest экземпляр, который имеет метод findModelOrFail(), и для отдельного ресурса (например, при просмотре страницы сведений о ресурсе) запрос также получает параметр resourceId.

Таким образом, основываясь на resourceId присутствии в запросе, я теперь могу определить, нахожусь ли я в контексте операции с одним ресурсом. Затем я извлекаю модель ресурса с этим идентификатором и проверяю его атрибут is_banned для разрешения доступных действий для ресурса.

Логика разрешения моих действий закончилась так:

public function actions(Request $request)
{
    if ($request->resourceId !== null) {
        $product = $request->findModelOrFail($request->resourceId);

        if ($product->is_banned) {
            return [];
        }
    }

    return [new Actions\BanProduct];
}

Обратите внимание, что метод findModelOrFail() может быть вызван без аргумента $resourceId и автоматически получит значение resourceId из запроса в таком сценарии, но намерение кода будет более ясным при его непосредственном указании.

...