Evento de Campos Disparáveis do Modelo
O evento de campos despacháveis é um conceito que garante o disparo de eventos quando uma propriedade do modelo é alterada. Diferentemente dos eventos regulares do Model, que são despachados quando uma ação específica é realizada (salvar, atualizar, excluir, etc.), aqui temos uma implementação mais profunda que só é acionada se um atributo específico de um modelo tiver sido alterado.
O motivo dessa implementação foi evitar despachar e escutar eventos quando isso não é necessário. Por exemplo, um pedido no NexoPOS pode ser atualizado de várias maneiras. Toda vez que o pedido é atualizado, temos listeners padrão prontos para executar uma ação específica. Não seria melhor, quando o cliente atribuído for alterado, calcular relatórios para os clientes anteriores e recentes? Não seria melhor se pudéssemos notificar o motorista apenas quando o status da entrega passar de “pendente” para “pronto para entrega”? É exatamente para isso que serve este recurso.
Implementação
A implementação dessa funcionalidade consiste apenas em fornecer um array $dispatchableFieldsEvents no modelo em que queremos disparar o evento. Nesse modelo, forneceremos propriedades e eventos relacionados assim:
<?php
namespace Modules\YourModule\Models;
use App\Models\NsModel;
use Modules\YourModule\Events\DeliveryChangedEvent;
class Order extends NsModel
{
public $dispatchableFieldsEvents = [
'delivery_status' => DeliveryChangedEvent::class
];
}
Agora precisamos definir o evento, pois ele não apenas recebe o modelo como parâmetro, mas também o valor anterior e o novo da propriedade:
<?php
namespace Modules\YourModule\Events;
use App\Models\Order;
class DeliveryChangedEvent
{
public function __construct( public Order $order, public mixed $previous, public mixed $new )
{
// ...
}
}
A partir daqui, você pode ouvir com segurança este evento do nosso listener de eventos assim:
<?php
namespace Modules\YourModule\Listeners;
use Modules\YourModule\Events\DeliveryChangedEvent;
use Moduels\YourModules\Services\DriverService;
class DeliveryChangedEventListener
{
public function __construct( public DriverService $driverService ){
{
// ...
}
public function handle( DeliveryChangedEvent $event )
{
if ( $event->previous === 'pending' && $event->new === 'ready-for-delivery' ) {
$this->driverService->notifyAssignedDriver( $event->order );
}
}
}