loading...

Introducing Laravel Observers.

drumzminister profile image Elisha Ukpong Originally published at Medium on ・4 min read

Laravel Observers

Laravel framework comes with lots of awesome features, the outstanding one for me is the model observers.

According to the Laravel framework’s documentation:

If you are listening for many events on a given model, you may use observers to group all of your listeners into a single class. Observers classes have method names which reflect the Eloquent events you wish to listen for. Each of these methods receives the model as their only argument. The make:observer Artisan command is the easiest way to create a new observer class.

The observers helps me to declutter my controller of clean-up codes that I might have to run before or after making a model event, and also gives me a way to plug into the model’s event’s lifecycle and run any logic I might see fit.

The model events that can be observed are spread across the model’s CRUD and includes:

  • Retrieved
  • Creating
  • Created
  • Updating
  • Updated
  • Saving
  • Saved
  • Deleting
  • Deleted
  • Restoring
  • Restored

The above events can be observed for every model in the Laravel Framework and business logic attached to it, you can also dispatch custom events from the observer and listen to it from other parts of your application.

You might not see yourself using the observer class just yet and that is fine, having fair knowledge about it too, is okay.

Before that, to create an observer class, run:

php artisan make:observer

(replace observerName with the name of the model you are observing).

This will create a folder in your application’s app directory called Observers and store the observer class.

<?php

namespace App\Observers;

class BankObserver
{
    // an empty observer class
}

From here you can populate the classes with methods that match events I listed earlier, it is worthy to note that you can attach a model to an observer when creating the observer, like:

php artisan make:observer -m=

This will create the class with some method filled in by default, see below.

<?php

namespace App\Observers;

use App\Task;

class Task
{
_/\*\*  
     \* Handle the task "created" event.  
     \*  
     \*_ **_@param_** _\App\Task $task  
     \*_ **_@return_** _void  
     \*/_ public function created(Task $task)
    {
        //
    }

_/\*\*  
     \* Handle the task "updated" event.  
     \*  
     \*_ **_@param_** _\App\Task $task  
     \*_ **_@return_** _void  
     \*/_ public function updated(Task $task)
    {
        //
    }

_/\*\*  
     \* Handle the task "deleted" event.  
     \*  
     \*_ **_@param_** _\App\Task $task  
     \*_ **_@return_** _void  
     \*/_ public function deleted(Task $task)
    {
        //
    }

_/\*\*  
     \* Handle the task "restored" event.  
     \*  
     \*_ **_@param_** _\App\Task $task  
     \*_ **_@return_** _void  
     \*/_ public function restored(Task $task)
    {
        //
    }

_/\*\*  
     \* Handle the task "force deleted" event.  
     \*  
     \*_ **_@param_** _\App\Task $task  
     \*_ **_@return_** _void  
     \*/_ public function forceDeleted(Task $task)
    {
        //
    }
}

You might be wondering what model action triggers what observer action, I’ll briefly explain the different methods and what triggers them.

  • Retrieved — This observer method is called when a model record is retrieved from the database.

Model::findOrFail($id); //this triggers the retrieved method in the observer class

  • Creating — This observer method is called when a model record is in the process of creation, and not yet stored into the database, this is before the id, and default timestamps are generated for the model, at this point you can dynamically check for and assign a default value to a missing column.
  • Created — This observer method is called after a model record is created successfully. If there is an error in the process of creation, say a missing column data, this method doesn’t get called.

Model::create([]); //this triggers the creating method first, then created method in the observer class.

  • Updating — This observer method is called when a model record is in the updating process, at this point, the updates has not yet been persisted to the database.
  • Updated — This observer method is called after a model record is updated successfully. If there is an error in the process of updating, this method doesn’t get called.

Model::update([]); //this triggers the creating method first, then created method in the observer class.

  • Saving and Saved — These model observer methods might seem a bit like a swiss army knife, it gets called before and after any event that requires persistence of data to the database, so if you’re creating a new model record, the saving method runs first, then the creating method, then the created method and finally the saved method, the same routine applies when updating a model, saving, updating, updated, saved.
  • Deleting — This observer method is called when a model record is in the deletion process, at this point, the record has not yet been deleted from the database, and using its id to retrieve it from the database will return appropriate data.
  • Deleted — This observer method is called after a model record is successfully deleted, at this point, the record has been deleted from the database.

Model::destroy($id);

  • Restoring and Restored — These observer methods are called when a deleted model record is restored (using soft deletes implementation)

Important things to note:

  • The updating and updated methods only run when the update changes a column of the model in the database, as such, if the update request does not effect a change, the updating and updated observers don’t trigger, only the saving and saved methods get triggered.
  • When restoring a deleted record, series of methods gets triggered one after the other, retrieved, restoring, saving, updating, updated, saved, then restored.

In any case where you want to make a model event without triggering any observer method, you can save it without observer events. An example of a method to use when creating a model without triggering any of the events:

public function saveQuietly(array $options = [])
{
    return static::_withoutEvents_(function () use ($options) {
        return $this->save($options);
    });
}

Note: This method should be added in the respective model.

You can refactor it to suit other model events, as necessary.

Finally, the last part, binding the observer to a particular model.

This can be done in the boot method of the AppServiceProvider’s class:

_/\*\*  
 \* Bootstrap any application services.  
 \*  
 \*_ **_@return_** _void  
 \*/_ public function boot()
{
    Model::_observe_(Observer::class);
}

Model is the model to be observed and observer is the observer class

This ends the introduction to Laravel observers, and I hope it was enlightening to you.


Discussion

pic
Editor guide