I have a resource controller and want to add an extra custom policy method for destroyMany In which I would check if the user is admin before deleting many.
The default methods work fine
Controller Method | Policy Method |
---|---|
index | viewAny |
show | view |
create | create |
store | create |
edit | update |
update | update |
destroy | delete |
destroyMany | destroyMany |
Controller destroyMany method is called, the policy isn't Or should I stick to Gates for this extra method? The docs say I can have any name for the methods and policies, How can both be linked?
destroyMany->destroyMany or destroyMany->deleteMany would be a good setup.
And would be a great addition to my resource controller (where it should reside)
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
}
}
policy
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
}
}
To get the addition policy method to work you will need to update the resourceAbilityMap
for the controller. Adding the following to your controller should do the trick:
protected function resourceAbilityMap()
{
return array_merge(parent::resourceAbilityMap(), [
'destroyMany' => 'deleteMany'
]);
}
Also, if you don't return anything from your deleteMany
policy method it will result in a 403.
If your route/controller method isn't receiving an instance of the model then you will also need to update the array returned from the resourceMethodsWithoutModels
method:
protected function resourceMethodsWithoutModels()
{
return array_merge(parent::resourceMethodsWithoutModels(), ['destroyMany']);
}