I'm trying to sync my database with an external service.
I'm using Algolia search in a couple of places across a web application.
It's indexed with a couple of models however I need it to re-index in the event that any changes are made to the database i.e. when multiple model events are fired.
My first approach was to action everything within the boot method of the 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();
});
}
}
This is my approach to avoid multiple conditionals using the standard model functions exampled in the docs.
However I'm assuming there's a better way using Laravel Event Listeners.
namespace App\Listeners;
class OrderEventListener
{
// handlers
public function subscribe($events)
{
$events->listen(
// model events
);
}
}
Although I'm unsure how to tap into the model events in the listen method.
I would strongly recommend adding your own event and handler for this situation.
In your Product
and Order
classes you can override the boot
method of the model:
class Product extends Model
{
protected static function boot()
{
parent::boot();
self::created(function($product) {
event(new ProductCreatedEvent($product));
});
}
}
You'll need to create your own ProductCreatedEvent
object. Now in the EventServiceProvider
you will want to add to the listeners array;
protected $listeners = [
'App\Events\ProductCreatedEvent' => [
'App\Listeners\UpdateAlgoliaProductIndex',
]
];
Once you've set this up you can actually run php artisan event:generate
and this will create the event object and listener for you. I'll skip the event object as it's quite simple it purely takes the product that was created and sends it through to the UpdateAlgoliaProductIndex
listener.
Now in your listener you will have something like the following:
class UpdateAlgoliaProductIndex
{
public function handle($event)
{
Product::reindex();
Product::setSettings();
}
}
The reason I suggest this approach is you can then queue the listener using the ShouldQueue
interface, meaning that you don't block the request whilst waiting for your app to reindex with Algolia leading to a better experience for your users.
You can read more about the event objects and listeners here.
An alternative option is to use a model observer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With