laravellaravel-eventslaravel-models

Find which model method is triggering the Event


I'm using Laravel's Event & Listener functionality to detect the following model actions and trigger some application logic.

app/models/MealFood

/**
 * The event map for the model.
 *
 * Allows for object-based events for native Eloquent events.
 *
 * @var array
 */
protected $dispatchesEvents = [
    'created'  => MealFoodEvent::class,
    'updated'  => MealFoodEvent::class,
    'deleted'  => MealFoodEvent::class
];

app/events/MealFoodEvent

public $mealFood;

/**
 * Create a new event instance.
 *
 * @param MealFood $mealFood
 */
public function __construct(MealFood $mealFood)
{
    $this->mealFood = $mealFood;
}

app/listeners/MealFoodListener

public function handle(MealFoodEvent $event)
{
    $mealFood = $event->mealFood;
}

Is it possible to detect what model action triggered the event? I want to be able to know if the record triggering the event was created/updated/deleted. Right know I'm using soft deletes to check if the record was deleted but how can I know if the record was updated or created?


Solution

  • Create 3 additional classes:

    MealFoodCreatedEvent.php

    class MealFoodCreatedEvent extends MealFoodEvent {}
    

    MealFoodUpdatedEvent.php

    class MealFoodUpdatedEvent extends MealFoodEvent {}
    

    MealFoodDeletedEvent.php

    class MealFoodDeletedEvent extends MealFoodEvent {}
    

    Modify your model:

    protected $dispatchesEvents = [
        'created'  => MealFoodCreatedEvent::class,
        'updated'  => MealFoodUpdatedEvent::class,
        'deleted'  => MealFoodDeletedEvent::class
    ];
    

    Then in your event handler you can just do:

    public function handle(MealFoodEvent $event)
    {
        $mealFood = $event->mealFood;
        if ($event instanceof MealFoodCreatedEvent) { 
           // the event was "created
        }
    }
    

    The signature for handle still works because all your events extend MealFoodEvent

    You can also make MealFoodEvent abstract since you will never need to create an instance of it directly.