Nothings Found.

How to Use Model Observers in Laravel

Created: 6 days ago Category: Laravel Estimated time read: 3 Mins

TABLE OF CONTENT

  • Introduction
  • Prequisite
  • Laravel Model Events
  • Laravel Model Observer
  • Real Life Example
  • Tips
  • Conclusion

Introduction

Laravel's Eloquent OM is the rock-solid implementation of Active Record. It has many features includes Observers, Laravel implements Observer Pattern to fire some events, which can be listened to hook into, when various actions are performed on a model.

Requisite

You must have the least basic knowledge in laravel and how to generate models and knowledge in MVC Pattern and PHP in general.

Laravel Model Events

If you worked before in a medium to large scale project with laravel, you may notice you need to fire an event in some situation to keep your project nice and clean and easy to maintain. One of the Events in laravel is Model Events, that let you do some actions after the model saved, saving ...

Let's take an example, imagine You have Article model, and you want to set a slug automatically to saving the article. Instead of setting the slug when the articles got saved:

Article::create([
    'title'  => $name,
    'slug'  => Str::slug($name),
]);

You can do the following:

use Illuminate\Support\Str;

class Article extends Model
{
    ...

    protected static function boot()
    {
        parent::boot();

        static::saving( function ($model) {
            $model->slug = Str::slug($model->title);
        })
    }
}

This method is very straight forward, because if you have a multiple models requires a slug, you can a single Trait and use this method into it and implement the trait in every model requires a slug to be filled. I hope you got the idea.

The saving event is one of the provided events that Eloquent provides:

  • retrieved: after a record has been retrieved.
  • creating: before a record has been created.
  • created: after a record has been created.
  • updating: before a record is updated.
  • updated: after a record has been updated.
  • saving: before a record is saved (either created or updated).
  • saved: after a record has been saved (either created or updated).
  • deleting: before a record is deleted or soft-deleted.
  • restoring: before a soft-deleted record is going to be restored
  • restored: after a soft-deleted record has been restored.

You can use any of the methods listed above like we did before with saving

Laravel Model Observers

If you are planing to use more than one of the listed events above (depend on of your project), it is not a good idea to place all of them in your model. Laravel solved you issue and provided you with observer command to generate class contain all the available events, you can generate observer class like so:

php artisan make:observer ArticleObserver --model=Article

As the command tell, you are generating an observer class for the article model, and you can change it to the needed model.

The generated Observer leaves in app/Observers folder and contain the code below:

namespace App\Observers;

use App\Models\Post;

class PostObserver
{
    /**
     * Handle the article "created" event.
     *
     * @param  \App\Models\Article  $article
     * @return void
     */
    public function created(Article $article)
    {
        //
    }

    /**
     * Handle the article "updated" event.
     *
     * @param  \App\Models\Article  $article
     * @return void
     */
    public function updated(Article $article)
    {
        //
    }

    /**
     * Handle the article "deleted" event.
     *
     * @param  \App\Models\Article  $article
     * @return void
     */
    public function deleted(Article $article)
    {
        //
    }

    /**
     * Handle the article "restored" event.
     *
     * @param  \App\Models\Article  $article
     * @return void
     */
    public function restored(Article $article)
    {
        //
    }

    /**
     * Handle the article "force deleted" event.
     *
     * @param  \App\Models\Article  $article
     * @return void
     */
    public function forceDeleted(Article $article)
    {
        //
    }
}

After the observer class generated successfully you need to register it inside AppServiceProvider in app/Providers/AppServiceProvider folder inside the boot() method

...
public function boot()
{
    Article::observe(ArticleObserver::class);
}
...

Now we have successfully added a model observer to Article model, and you are good to go with your application.

Real Life Example

Some of you see the explanation above and other not (including me) so, we will build a small application to show you how to use them properly.

Now, we have a User model (came by default in laravel) and Article model generated before, normally the user have many articles and let's assume we deleted the user from our records, well. There're many scenarios on how to deal with the articles created by the deleted user but, let's delete his/her article as well.

You may want to define the relationship first:

class User extends Model
{
    public function articles()
    {
        return $this->hasMany(Article::class);
    }
}

Let's generate a new User Observer

php artisan make:observer UserObserver --model=User

After you registered the UserObserver inside AppServiceProvider as we do in ArticleObserver above, let's open it and make some modifications

class UserObserver
{
    /**
     * Handle the user "deleting" event.
     *
     * @param  \App\User  $user
     * @return void
     */
    public function deleting(User $user)
    {
        $user->articles()->delete();
    }
}

Note: You are not forced to keep the unneeded methods, and you may only keep the one who you are truly need it

So, All what we are doing here, after the user get delete the articles belongs to him deleted as well. That's all, Coll, isn't it?

Tips

Everything's in this world has limitation and the Model Observers among them. You should keep in mind while you are using the model observers the following:

  • When you use saved or saving hooks (events), you should never call the model's save method
  • If you are using saved hook and want to call the save method, then you should probably use the saving hook as well.
  • if your logic need to call model's save method. Then rethink your logic or avoid using observers.

If you're not familiar with save method here is a small definition from Laravel Documentation:

Eloquent provides convenient methods for adding new models to relationships. For example, perhaps you need to add a new comment to a post. Instead of manually setting the post_id attribute on the Comment model you may insert the comment using the relationship's save method:

use App\Models\Comment;
use App\Models\Post;

$comment = new Comment(['message' => 'A new comment.']);

$post = Post::find(1);

$post->comments()->save($comment);

Conclusion

Laravel Model Observers are a very powerful and useful features and helps to keep your code maintainable and easy to understand.

You should keep in mind the limitation above in the Tips section to avoid any problems with your code base.

That's it for today and if you have any questions about the Observers, you can ask me at any time.

If you enjoy with my articles you can follow me at Twitter for more Tips and Tricks about laravel.


Related Tags
Laravel Observers Events Models

About the Author

Author
I'm ossama and I'm a full stack web developer - telecommunications engineer - write about the tech in general

STAY TUNED

Subscribe to Our Newsletter and never miss our offers, latest news, Articles, etc. Our news letter sent once a week, every tuesday.