Quick Tip: The Convenient Magic of Eloquent Observers

Share this article

Quick Tip: The Convenient Magic of Eloquent Observers

If you’ve used Eloquent on medium to large projects before, you may have encountered a situation where you want to take action when something happens to your models. Eloquent provides a convenient way to do so.

Laravel Logo

The Observer Pattern

The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. – Wikipedia

In our case, Eloquent models can notify us about changes on a given model.

Model Events

Eloquent provides a handful of useful events to monitor the model state: creating, created, updating, updated, deleting, deleted, saving, saved, restoring, restored.

Notice the “ing/ed” difference.

  • creating: Called before saving the new member.
  • created: Called after saving the member.

Eloquent also fires similar events that we can listen for. The below example attaches a listener to the creating event on the Member model.

Event::listen("eloquent.created: App\\Member", function(Member $member) {
    // do something
});

Creating Observers

Let’s start by creating a new class under the App\Observers namespace and start defining our methods.

// app\Observers\MemberObserver.php

namespace App\Observers;

use App\Member;

class MemberObserver
{
    public function deleting(Member $member) {
        // do something
    }
}

We can use the event name as the method name for each one. We don’t have to define all the methods, just the ones that we want to use.

Every member can subscribe to multiple services, and every service contains many members. Let’s assume we don’t have cascade deletion set up for the associated members_services table, and we need to delete associated services on member deletion to avoid errors when accessing subscribed members for a service.

// app\Observers\MemberObserver.php

namespace App\Observers;

use App\Member;

class MemberObserver
{
    public function deleting(Member $member) {
        $member->services()->delete();
    }
}

Now, the last thing is to attach this observer to the appropriate model. We can do this anywhere we want, but the practical place to put it is inside the app\Providers\AppProvider.php file inside the boot method.

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Member::observe("App\\Observers\\MemberObserver");
    }
}

I know that the cascade deletion example was simple and could be done in the controller or directly via MySQL, but this is just a proof of concept.

The good thing about Eloquent observers is that we can abort the current action by returning a false value from the callback method:

class MemberObserver
{
    public function deleting(Member $member) {
        $member->deleted_at = Carbon::now();
        $member->save();

        return false;
    }
}

In the example above, we are soft deleting members and returning false to abort the actual delete action.


Eloquent has many hidden features, and this is one of them. You’ll see this used heavily in big applications and CMSes. If you have any questions or comments about Eloquent, be sure to post them below!

Frequently Asked Questions (FAQs) about Eloquent Observers in Laravel

What is the purpose of using Eloquent Observers in Laravel?

Eloquent Observers in Laravel are used to handle business logic that needs to occur before or after a particular database operation, such as creating, updating, deleting, or restoring model instances. They provide a simple, organized way of managing these events in a dedicated class, rather than having them scattered throughout your application. This makes your code cleaner, more manageable, and easier to maintain.

How do I create an Eloquent Observer in Laravel?

To create an Eloquent Observer in Laravel, you first need to create an observer class. This class will contain the methods that represent the Eloquent events you wish to hook into. Each of these methods will receive the model as their only argument. Laravel does not include a command for generating observers, so you’ll need to create this class manually in your app/Observers directory.

How do I register an Eloquent Observer?

Once you’ve created your observer class, you need to register it with the model it should observe. This is typically done in the boot method of one of your service providers. In this method, you should call the observe method on the model you wish to observe, passing in the class name of the observer.

Can I observe multiple models with a single observer?

Yes, you can observe multiple models with a single observer. However, it’s generally recommended to create a separate observer for each model to keep your code organized and maintainable. If you do choose to observe multiple models with a single observer, you’ll need to ensure that the observer methods can handle all the models correctly.

What are the available Eloquent events I can observe?

Laravel’s Eloquent ORM fires several events, allowing you to hook into various points in a model’s lifecycle. These events include ‘retrieved’, ‘creating’, ‘created’, ‘updating’, ‘updated’, ‘saving’, ‘saved’, ‘deleting’, ‘deleted’, ‘restoring’, and ‘restored’. Each of these events is fired at the appropriate time, and your observer methods can listen for any or all of these events.

Can I stop an Eloquent event from propagating in an observer?

Yes, you can stop an Eloquent event from propagating in an observer. If an observer’s method returns false, all remaining event listeners for the event will not be executed. This can be useful if you need to prevent a model from being saved or deleted under certain conditions.

How can I use Eloquent Observers for validation?

Eloquent Observers can be used for validation by listening for the ‘creating’ or ‘updating’ events. In the observer method for these events, you can perform any validation checks you need. If the validation fails, you can return false to prevent the model from being saved.

Can I use Eloquent Observers with soft deletes?

Yes, Eloquent Observers work with soft deletes. The ‘restoring’ and ‘restored’ events are fired when a soft deleted model is being restored. Similarly, the ‘deleting’ event is fired when a model is being soft deleted, and the ‘deleted’ event is fired after a model has been soft deleted.

How can I access the old values of a model in an observer?

You can access the old values of a model in an observer by using the getOriginal method on the model. This method returns the original values of the model’s attributes, allowing you to compare them with the model’s current values.

Can I use Eloquent Observers to log model changes?

Yes, Eloquent Observers are a great way to log model changes. You can listen for the ‘created’, ‘updated’, and ‘deleted’ events, and then log the changes in the observer methods for these events. This can be useful for auditing purposes, or for debugging your application.

Younes RafieYounes Rafie
View Author

Younes is a freelance web developer, technical writer and a blogger from Morocco. He's worked with JAVA, J2EE, JavaScript, etc., but his language of choice is PHP. You can learn more about him on his website.

design patterndesign patternseloquenteventslaravelobserverOOPHPPHPPHP Quick Tips
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week