Когда проект добавляется, я вызываю всех пользователей, у которых есть разрешение на его просмотр, чтобы сообщить им об этом.
Это происходит в слушателе:
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 пользователей впустую.
А поскольку событие и прослушиватель выполняются синхронно, пользователь, добавляющий проект, должен ждать, пока это произойдет.
Как я могу ускорить это?
Редактировать: Хорошо, можно ставить слушателей в очередь. Однако было бы здорово улучшить этот код.
Я вижу, к чему вы клоните с этим вопросом. Я мог бы изучить логику этой политики и использовать ее для ускорения этого процесса. Но когда политика изменится, можно забыть обновить это. Приходят баги.
Ну, в зависимости от логики вашей политики, я собирался предложить пару вещей, но если вы уже знаете, что это не поможет, то не обращайте внимания :)
На самом деле проект — это всего лишь пример. У меня есть несколько слушателей, которым нужно найти пользователей, которые будут уведомлены. У меня есть группы с разрешениями, и большую часть времени политика проверяет, есть ли у пользователя разрешение. Но, как я уже сказал, все становится опасным, когда добавляется дополнительное условие.






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