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

Когда проект добавляется, я вызываю всех пользователей, у которых есть разрешение на его просмотр, чтобы сообщить им об этом.
Это происходит в слушателе:

use App\Models\User;
use Illuminate\Support\Facades\Gate;

// ...

$notifiables = User::all()->filter(function(User $user) use($event) {
    return Gate::forUser($user)->allows('view', $event->project);
});

Это работает. Но когда у меня в системе 1000 пользователей и 5 могут просматривать проект, я перебираю более 995 пользователей впустую.
А поскольку событие и прослушиватель выполняются синхронно, пользователь, добавляющий проект, должен ждать, пока это произойдет.

Как я могу ускорить это?

Редактировать: Хорошо, можно ставить слушателей в очередь. Однако было бы здорово улучшить этот код.

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

Rwd 27.02.2019 10:15

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

user10517872 27.02.2019 10:23

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

Rwd 27.02.2019 14:37

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

user10517872 27.02.2019 14:59
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
4
55
2

Ответы 2

Я не знаком с фасадом ворот, но если он находится в модели с отношениями, вы можете использовать whereHas :

$users = App\User::whereHas('permissions', function ($q) use ($event) {
    $q->where('name', 'view')->where('model_id', $event->project->id);
})->get();

https://laravel.com/docs/5.7/eloquent-relationships#querying-relationship-existence

Вы можете использовать трейт Laravel Notifications, чтобы подписавшийся пользователь мог получать уведомления. Эти уведомления могут быть поставлены в очередь для обработки позже, отправлены по электронной почте/sms/slack, сохранены в БД или использованы для рассылки сообщений, как в вашем случае использования.

Сделать новое уведомление

php artisan make:notification InvoicePaid

Использовать черту подлежащий уведомлению

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;
}

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

use App\Notifications\InvoicePaid;

$user->notify(new InvoicePaid($invoice));

https://laravel.com/docs/5.8/уведомления

Учебник: https://code.tutsplus.com/tutorials/notifications-in-laravel--cms-30499

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

user10517872 27.02.2019 11:16

О, я вижу. Я неправильно понял проблему. Значит, это проблема дизайна БД, а не проблема Laravel? Пробовали ли вы создать таблицу для ваших уведомлений с user_id в качестве внешнего ключа? $notifable_users = Notification::select('user_id')->get();

Peter-M 27.02.2019 11:30

Другие вопросы по теме