Как проверить политику для каждого результата, когда пользователь запросил удаление нескольких записей в laravel? - PullRequest
0 голосов
/ 11 января 2019

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

В конце я должен вернуть все идентификаторы записей, которые были удалены, и оставшиеся, для которых пользователь не имеет определенной роли. Есть ли эффективный способ удаления записей на основе ролей.


Один из способов, с помощью которого я могу думать, - это то, что я получу записи, а затем переберу каждую запись и для каждой записи, я проверю, является ли зарегистрированный пользователь владельцем этой записи или у него есть определенный роль или нет. Если он есть, тогда я удалю эту запись. Примерно так:

$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 может содержать сочетание авторизованных и неавторизованных идентификаторов.

1 Ответ

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

Если вы используете пакет, который включает политики, разве вы не должны проверять, позволяет ли политика авторизованному пользователю удалять ресурс?

Вы «можете» создать метод политики, который принимает несколько идентификаторов, ничто не мешает вам сделать это, но большинство политик, вероятно, лучше всего работают с экземпляром ресурса.

Пример:

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

Поскольку удаления обычно не выполняются в приложениях, выбор всех ресурсов и передача каждого экземпляра отдельно для проверки авторизации перед удалением может показаться неэффективным, но практически не будет таким заметным.

Прочтите метод политики авторизации laravel , чтобы узнать больше о написании политик. Единственный параметр, который должен существовать - это $ user, кроме этого, вы определяете, что передается и используется в методе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...