0

bulk_destroy在控制器中有一个方法,它接受用户想要删除的 id 数组。我必须检查每条记录的用户是该记录的所有者还是他具有删除该记录的特定角色。

最后,我必须返回所有被删除的记录 ID,以及用户没有特定角色的剩余记录 ID。有什么有效的方法可以根据角色删除记录。


我可以考虑的一种方法是获取记录,然后遍历每条记录,对于每条记录,我将检查登录用户是否是该记录的所有者,或者他是否具有特定角色. 如果他有,那么我将删除该记录。如下所示:

$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);

但在那种情况下,对于每条记录,它都会进行数据库查询以删除记录,我认为这不是正确的方法。


我能想到的其他解决方案是:

$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);

实际上我正在考虑以下解决方案:

$posts = Post::withTrashed()->whereIn('_id', $request->ids);
$deleted_post_ids = $posts->forceDelete(); // it should take care of authorization

但是如何约束forceDelete()只删除特定的记录。有什么办法可以覆盖forceDelete()方法吗?

或者非常感谢一些优雅的解决方案。


更新

我不能使用政策,因为如果我使用,

$user->can('deleteBulk', [Post::class, $ids]);

它返回true/false,那么我将如何只删除用户被授权的那些资源?因为在某些情况下$ids可能包含授权和未授权的 ID。

4

1 回答 1

1

如果您使用的是启用策略的包,您不应该检查策略是否允许 auth 用户删除资源吗?

您“可以”构建一个接受多个 ID 的策略方法,没有什么可以阻止您这样做,但大多数策略可能最适合资源实例。

例子:

$user->can('deleteBulk', [Post::class, $ids]);

由于删除通常不会在应用程序中经常执行,因此在删除之前选择所有资源并单独传递每个实例以检查授权可能听起来效率低下,但实际上不会那么明显。

阅读laravel 授权策略方法,了解更多关于编写策略的信息。唯一需要存在的参数是 $user,除此之外,您可以定义方法中传递和使用的内容。

于 2019-01-11T13:56:14.933 回答