updateorcreate update mass example delete create assignment php laravel laravel-5 laravel-5.2 algolia

php - update - mass assignment laravel



Laravel Multiple Model Events (2)

Estoy tratando de sincronizar mi base de datos con un servicio externo.

Estoy usando la búsqueda de Algolia en un par de lugares a través de una aplicación web.

Está indexado con un par de modelos, sin embargo, lo necesito para volver a indexar en caso de que se realicen cambios en la base de datos, es decir, cuando se disparan varios eventos del modelo.

Mi primer enfoque fue actuar de todo dentro del método de arranque de 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(); }); } }

Este es mi enfoque para evitar condicionales múltiples utilizando las funciones de modelo estándar que se muestran en los documentos .

Sin embargo, estoy asumiendo que hay una mejor manera de utilizar Laravel Event Listeners.

namespace App/Listeners; class OrderEventListener { // handlers public function subscribe($events) { $events->listen( // model events ); } }

Aunque no estoy seguro de cómo acceder a los eventos modelo en el método de escucha .


Recomiendo encarecidamente agregar su propio evento y controlador para esta situación.

En sus clases de Product y Order , puede anular el método de boot del modelo:

class Product extends Model { protected static function boot() { parent::boot(); self::created(function($product) { event(new ProductCreatedEvent($product)); }); } }

Tendrá que crear su propio objeto ProductCreatedEvent . Ahora, en EventServiceProvider , querrá agregar a la matriz de oyentes;

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

Una vez que haya configurado esto, puede ejecutar el php artisan event:generate y esto creará el objeto de evento y el oyente por usted. Voy a omitir el objeto del evento, ya que es bastante simple, simplemente toma el producto que se creó y lo envía al oyente UpdateAlgoliaProductIndex .

Ahora en su oyente tendrá algo como lo siguiente:

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

La razón por la que sugiero este enfoque es que puede ShouldQueue cola al oyente que usa la interfaz ShouldQueue , lo que significa que no bloquea la solicitud mientras espera que su aplicación reindexe con Algolia, lo que redunda en una mejor experiencia para sus usuarios.

Puede leer más sobre los objetos y oyentes del evento aquí .

Una opción alternativa es usar un observador modelo .


Con algo de investigación, me he encontrado con suscriptores del evento Laravel, que es más parecido a lo que estaba buscando, así que lo he presentado como su propia respuesta.

Creo que esto produce un código más conciso que tener oyentes para cada evento.

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'' ); } }

Mantendré la respuesta de marcus.ramsden como marcada, pero esto probablemente sea muy relevante para las personas que se encuentren con esta pregunta.