Eloquent 5.7: Creation-Event

4.7k views Asked by At

I would like to automate the allocation of data to a property (i.e. customized ID-number) as soon as a new item has been created.

I understood that the example given in the next box is unfortunally not possible anymore with Eloquent 5.7!

Not possible in Eloquent 5.7:

use Illuminate\Database\Eloquent\Model as Eloquent;

class Message extends Eloquent {
    ...
    public static function boot() {
        parent::boot();

        self::creating(function ($model) {
            $model->ID = 1234; // 1234 shall be replaced later by a function
        });
    }
    ...
}

For Eloquent 5.7:

As far as I understood, I have to define now a seperate class and link it in my model to the requested event like this:

use Illuminate\Database\Eloquent\Model as Eloquent;

class Message extends Eloquent {
    ...
    protected $dispatchesEvents = [
        'creating' => MessageCreated::class,
    ];
    ...
}

But my problem is now, that I don't know how I create this extra class "MessageCreated". All the tutorial I have read and seen is using the full set of Laravel (doing some terminal comands with ARTISAN ...). But in my envoirement I have only Illuminate/Eloquent installed, so I have no idea how to proceed.

Thanks for ideas!

Tim

1

There are 1 answers

2
Oluwafemi Sule On

Illuminate\Database\Eloquent\Model::creating (available through the Illuminate\Database\Eloquent\Concerns\HasEvents trait) for registering a creating model event with the dispatcher is still supported in version 5.7 of the Laravel framework.

This other way of setting an event class in the event map for the model allows to dispatch a custom event for the creating model event.

The event class MessageCreated is just a PHP class whose constructor is passed the Eloquent model instance in this case.

This means that where you decide to keep it is left to your judgment.

For instance, lets say that MessageCreated.php is added in app/Events folder in App\Events namespace; the contents thereof will be

<?php
// app/Events/MessageCreated.php

namespace App\Events;

use App\Message;

final class MessageCreated
{
    public function __construct(Message $message) {
        $this->message = $message;
    }

}

In this situation, the message ID can be added in the constructor of the MessageCreated event; I can't rest easy with it done there as an event shouldn't mutate its payload.

A listener can be registered with the EventServiceProvider to handle this type of event.

The listener can be created in app/Listeners folder. e.g.

<?php
// app/Listeners/AddMessageId.php

namespace App\Listeners;

class AddMessageId
{
    public function handle($event)
    {
        $event->message->ID = 1234;
    }
}

In app/providers/EventServiceProvider.php, register the event listener in the listen property.

protected $listen = [
    'App\Events\MessageCreated' => [
        'App\Listeners\AddMessageId',
    ],
];

There is builtin tooling that can be used to create event classes. The classes created this way are namespaced in App\Events.

Running the following command bootstraps the MessageCreated class; you only need to fill the implementation.

php artisan make:event MessageCreated

php artisan make:listener AddMessageId