Laravel 多个模型事件
Laravel Multiple Model Events
我正在尝试将我的数据库与外部服务同步。
我在 Web 应用程序的几个地方使用 Algolia 搜索。
它用几个模型建立了索引,但是我需要它在对数据库进行任何更改(即触发多个模型事件时)的情况下重新建立索引。
我的第一个方法是在 AppServiceProvider
的 boot 方法中执行所有操作
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();
});
}
}
这是我使用 docs.
中示例的标准模型函数来避免多重条件的方法
但是我假设有更好的方法使用 Laravel 事件侦听器。
namespace App\Listeners;
class OrderEventListener
{
// handlers
public function subscribe($events)
{
$events->listen(
// model events
);
}
}
尽管我不确定如何利用 listen 方法中的模型事件。
我强烈建议为这种情况添加您自己的事件和处理程序。
在您的 Product
和 Order
类 中,您可以覆盖模型的 boot
方法:
class Product extends Model
{
protected static function boot()
{
parent::boot();
self::created(function($product) {
event(new ProductCreatedEvent($product));
});
}
}
您需要创建自己的 ProductCreatedEvent
对象。现在在 EventServiceProvider
中,您将要添加到侦听器数组;
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 重新编制索引时不会阻止请求,从而获得更好的体验为您的用户。
您可以阅读有关事件对象和侦听器的更多信息here。
另一种选择是使用 model observer。
经过一些挖掘,我遇到了 Laravel 事件 subscribers,它更类似于我正在寻找的东西,所以我将其作为自己的答案提交。
我认为这比每个事件都有监听器更简洁。
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 标记的答案,但这可能与遇到此问题的人非常相关。
我正在尝试将我的数据库与外部服务同步。
我在 Web 应用程序的几个地方使用 Algolia 搜索。
它用几个模型建立了索引,但是我需要它在对数据库进行任何更改(即触发多个模型事件时)的情况下重新建立索引。
我的第一个方法是在 AppServiceProvider
的 boot 方法中执行所有操作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();
});
}
}
这是我使用 docs.
中示例的标准模型函数来避免多重条件的方法但是我假设有更好的方法使用 Laravel 事件侦听器。
namespace App\Listeners;
class OrderEventListener
{
// handlers
public function subscribe($events)
{
$events->listen(
// model events
);
}
}
尽管我不确定如何利用 listen 方法中的模型事件。
我强烈建议为这种情况添加您自己的事件和处理程序。
在您的 Product
和 Order
类 中,您可以覆盖模型的 boot
方法:
class Product extends Model
{
protected static function boot()
{
parent::boot();
self::created(function($product) {
event(new ProductCreatedEvent($product));
});
}
}
您需要创建自己的 ProductCreatedEvent
对象。现在在 EventServiceProvider
中,您将要添加到侦听器数组;
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 重新编制索引时不会阻止请求,从而获得更好的体验为您的用户。
您可以阅读有关事件对象和侦听器的更多信息here。
另一种选择是使用 model observer。
经过一些挖掘,我遇到了 Laravel 事件 subscribers,它更类似于我正在寻找的东西,所以我将其作为自己的答案提交。
我认为这比每个事件都有监听器更简洁。
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 标记的答案,但这可能与遇到此问题的人非常相关。