I have a method bulk_destroy
in the controller that accepts an array of ids that user wants to delete. I've to check for each record whether the user is the owner of that record or he has the specific role to delete that record.
At the end I've to return the all record ids which get deleted and the remaining one for which user does not have specific role. Is there any efficient way to delete records on the basis of role.
One way I can think about is that I'll fetch the records and then I'll iterate over each record and for each record, I'll check whether logged in user is the owner of that record or he has the specific role or not. If he has then I'll delete that record. Something like below:
$posts = Post::withTrashed()->whereIn('_id', $request->ids);
$deleted_post_ids = [];
$not_deleted_post_ids = [];
foreach($posts as $post) {
if ($post->owner_id == auth()->id() || auth()->user()->hasAnyRole(['super-admin', 'admin', 'moderator']) {
array_push($deleted_post_ids, $post->forceDelete());
}
else {
array_push($not_deleted_post_ids, $post->id);
}
}
return response()->json([
'success' => [
'message' => 'posts deleted successfully',
'ids' => $deleted_post_ids,
],
'error' => [
'message' => 'not authorized',
'ids' => $not_deleted_post_ids,
],
], 200);
But in that case, for each record, it is making a database query to delete the record, which I think is not the correct way to go.
Other solution that I can think of is:
$posts = Post::withTrashed()->whereIn('_id', $request->ids);
$deleted_post_ids = [];
$not_deleted_post_ids = [];
if (!auth()->user()->hasAnyRole(['super-admin', 'admin', 'moderator'])
{
$posts = $post->where('owner_id', auth()->id());
}
$deleted_post_ids = $posts->forceDelete();
$not_deleted_post_ids = array_diff($request->ids, $deleted_post_ids);
Actually I'm thinking of below soulution:
$posts = Post::withTrashed()->whereIn('_id', $request->ids);
$deleted_post_ids = $posts->forceDelete(); // it should take care of authorization
But how to constraint forceDelete()
to delete only specific records. Is there any way I can override forceDelete()
method?
Or some elegant solution is much appreciated.
Update
I can't use policy, because if I use,
$user->can('deleteBulk', [Post::class, $ids]);
It returns true/false, then how will I delete only those resources which user is authorized to? because in some cases $ids
may contain a mix of authorized and unauthorized ids.