Laravel, у которого есть собственный метод контроллера с пользовательским методом политики?

У меня есть контроллер ресурсов, и я хочу добавить дополнительный настраиваемый метод политики для destroyMany, в котором я бы проверял, является ли пользователь администратором, прежде чем удалять многие.

Методы по умолчанию работают нормально

Controller Method Policy Method
index viewAny
show view
create create
store create
edit update
update update
destroy delete
destroyMany destroyMany

Метод destroyMany контроллера вызывается, а политика — нет. Или я должен придерживаться Гейтса для этого дополнительного метода? В документах говорится, что у меня может быть любое имя для методов и политик. Как они могут быть связаны?

destroyMany-›destroyMany или destroyMany-›deleteMany будет хорошей установкой.

И было бы отличным дополнением к моему контроллеру ресурсов (там, где он должен находиться).

class ResourceController extends Controller
{
    public function __construct()
    {
      $this->middleware('auth:api');
      $this->authorizeResource(Resource::class, 'resource');
    }

    public function index()
    {

        return ResourceCollection::collection(Resource::all());
    }

    public function destroyMany(Request $request)
    {
        // gets called but needs a policy which isn't called
    }
}

политика

class ResourcePolicy
{
    use HandlesAuthorization;

    /**
     * Create a new policy instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    public function viewAny(User $user)
    {
        // works
        return $user->hasAnyRoles(['admin', 'superAdmin']);
    }

    public function delete(User $user, Resource $resource)
    {
       // works
        return $user->hasAnyRoles(['admin', 'superAdmin']);
    }

    public function deleteMany(User $user, Resource $resource)
    {
        // not called because the controller method needs to be hooked up, like the other methods
       
    }
}

person user14409370    schedule 09.03.2021    source источник
comment
Какую версию Laravel вы используете? Пожалуйста, не могли бы вы также показать код вашего контроллера.   -  person Rwd    schedule 09.03.2021
comment
Я отредактировал свой вопрос, это обычный контроллер ресурсов с политиками. Ларавель 8   -  person user14409370    schedule 09.03.2021


Ответы (1)


Чтобы метод добавления политики работал, вам необходимо обновить resourceAbilityMap для контроллера. Добавление следующего к вашему контроллеру должно помочь:

protected function resourceAbilityMap()
{
    return array_merge(parent::resourceAbilityMap(), [
        'destroyMany' => 'deleteMany'
    ]);
} 

Кроме того, если вы ничего не вернете из своего метода политики deleteMany, это приведет к ошибке 403.

Если ваш метод маршрута/контроллера не получает экземпляр модели, вам также потребуется обновить массив, возвращаемый методом resourceMethodsWithoutModels:

protected function resourceMethodsWithoutModels()
{
    return array_merge(parent::resourceMethodsWithoutModels(), ['destroyMany']);
}
person Rwd    schedule 09.03.2021
comment
Отличный ответ! Хотя 'destroyMany' => 'deleteMany' добавляется и возвращается через resourceAbilityMap, я все еще получаю 403, я отредактировал пример кода и добавил работающий метод удаления. deleteMany имеет ту же конструкцию. - person user14409370; 09.03.2021
comment
@user14409370 user14409370 Если вы ничего не вернете из метода политики, вы получите 403, поскольку ничего не возвращая, вы получите ложное значение. Извините, я должен был упомянуть. - person Rwd; 09.03.2021
comment
@user14409370 user14409370 Это ответило на ваш вопрос или у вас все еще есть проблемы? - person Rwd; 10.03.2021
comment
Все еще 403 при возврате true в политике для deleteMany, боюсь, ... ваша помощь очень ценится! - person user14409370; 10.03.2021
comment
@user14409370 user14409370 Извините, мне не пришло в голову, что вы не будете передавать экземпляр Resource маршруту/контроллеру. Я обновил ответ, чтобы показать, что вам также нужно добавить метод resourceMethodsWithoutModels в свой контроллер. - person Rwd; 10.03.2021
comment
Великолепно! resourceMethodsWithoutModels сделали свое дело! Я очень благодарна вам за помощь, вы показываете глубокие знания! Надеюсь, вы получите много бонусных баллов. ;-) - person user14409370; 10.03.2021
comment
@ user14409370 Рад, что смог помочь! - person Rwd; 11.03.2021