26th Oct 17By John Doe

About Observers in general

Observers have dedicated places where we can listen to our Eloquent events and handle the proper actions. The framework makes easy to use the observers. All we have to do is bind the models to the observers and move the logic from the models to their new place.

Creating the Service Provider

Let’s run the php artisan make:provider ObserverServiceProvider to generate our provider. As always we can find our new file in the app/Providers directory. After this step, our next job is to add the provider to the config file to let Laravel know about our new service.

Binding Observers to Models

In our ComposerServiceProvider’s boot method we can define our observer-model bindings. Let’s assume we are working with users, so firstly we need to create our UserObserver class and bind it to the User model.

// app/Providers/ObserverServiceProvider.php

<?php

namespace App\Providers;

use App\User;
use Illuminate\Support\ServiceProvider;
use App\Services\Observers\UserObserver;

class ObserverServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        User::observe(UserObserver::class);
    }
}

Now we can listen to the User model’s events. Also, we can handle the proper logic in a dedicated place, instead of messing up our models.

We can implement the following methods in our observers due to the Laravel documentation: creating/created, updating/updated, saving/saved, deleting/deleted, restoring/restored. All we have to do, to fill our observers with the events what we would like to listen. We can achieve this by defining methods named after the proper event.

Like in our previous post, we want to attach a randomly generated API token to our user before we record it to the database.

// app/Services/Observers/UserObserver.php

<?php

namespace App\Services\Observers;

use App\User;

class UserObserver
{
    /**
     * Listen to the user creating event.
     *
     * @param \App\User $user
     * @return void
     */
    public function creating(User $user)
    {
        $user->api_token = md5($user->email.str_random(10));
    }
}

We had the same result by listening and handling the model events in our user model’s boot method. But this is a cleaner approach to listening to multiple events.

Summary

From Laravel 5.4 we also have the chance to listen to events and bind them to listeners in the model’s $events property. It works the same way like the normal event / listener pairs. You can read more in the documentation.

We believe, little approaches like these make your application and code cleaner. It worths to refactor and reorganize your code when it’s getting messy. Most of the cases our models (especially the user model) can be huge, so it’s good to splice them and put the things to their dedicated place.