Laravel Multiple Model Events

Я пытаюсь синхронизировать свою базу данных с внешним сервисом.

Я использую поиск по Алголии в нескольких местах в веб-приложении.

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

Мой первый подход был к действию все в пределах ботинок метод AppServiceProvider

public function boot()
{
$events = ['created', 'updated', 'deleted', 'restored'];

// reindex handlers for models relevant to Algolia search
foreach ($events as $evt) {
Order::registerModelEvent($evt, function () {
Order::reindex();
});
Product::registerModelEvent($evt, function () {
Product::reindex();
Product::setSettings();
});
}
}

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

Однако я предполагаю, что есть лучший способ использовать Laravel Event Listeners.

namespace App\Listeners;

class OrderEventListener
{
// handlers

public function subscribe($events)
{
$events->listen(
// model events
);
}
}

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

9

Решение

Я настоятельно рекомендую добавить ваше собственное событие и обработчик для этой ситуации.

В вашем Product а также Order классы, которые вы можете переопределить boot метод модели:

class Product extends Model
{
protected static function boot()
{
parent::boot();

self::created(function($product) {
event(new ProductCreatedEvent($product));
});
}
}

Вам нужно будет создать свой собственный ProductCreatedEvent объект. Сейчас в EventServiceProvider вы хотите добавить в массив listeners;

protected $listeners = [
'App\Events\ProductCreatedEvent' => [
'App\Listeners\UpdateAlgoliaProductIndex',
]
];

После настройки вы можете запустить php artisan event:generate и это создаст объект события и слушателя для вас. Я пропущу объект события, так как он довольно прост, он просто берет созданный продукт и отправляет его в UpdateAlgoliaProductIndex слушатель.

Теперь в вашем слушателе у вас будет что-то вроде следующего:

class UpdateAlgoliaProductIndex
{
public function handle($event)
{
Product::reindex();
Product::setSettings();
}
}

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

Вы можете прочитать больше об объектах события и слушателях Вот.

Альтернативным вариантом является использование модельный наблюдатель.

7

Другие решения

С некоторыми копаниями я наткнулся на событие Laravel абоненты что больше похоже на то, что я искал, поэтому я представил его как собственный ответ.

Я думаю, что это дает более сжатый код, чем наличие слушателей для каждого события.

namespace App\Listeners;

use App\Events\OrderCreatedEvent;
use App\Events\OrderUpdatedEvent;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class OrderEventListener
{
/**
* Handle order created events.
*
* @param OrderCreatedEvent $event
*/
public function onOrderCreation(OrderCreatedEvent $event)
{
// do something
}

/**
* Handle order updated events.
*
* @param OrderUpdatedEvent $event
*/
public function onOrderUpdate(OrderUpdatedEvent $event)
{
// do something
}

/**
* Register the listeners for the subscriber.
*
* @param $events
*/
public function subscribe($events)
{
$events->listen(
'App\Events\OrderCreatedEvent',
'App\Listeners\OrderEventListener@onOrderCreation'
);

$events->listen(
'App\Events\OrderUpdatedEvent',
'App\Listeners\OrderEventListener@onOrderUpdate'
);
}
}

Я оставлю ответ marcus.ramsden отмеченным, но это, вероятно, очень актуально для людей, сталкивающихся с этим вопросом.

0

По вопросам рекламы [email protected]