Back to Course |
Laravel 11 Eloquent: Expert Level

Model Observers and Their Methods

If you want to perform some action when the Eloquent object is created or updated, it is usually done with the Observer class. It's like events and listeners in Laravel, but all the listeners related to the same Eloquent Model are grouped into one class called Observer.


Generate Observers

Observer can be generated using the Artisan command. Typically, you should prefix Observer with the Model name for the name. Additionally, you can pass --model option and provide the Model name.

php artisan make:observer UserObserver --model=User

The command will generate the UserObserver class in the app/Observers folder. And then, in that Observer class, you will find generated methods, created(), updated(), deleted(), restored(), and forcedDeleted(). The last two are for Soft Deletes.

<?php
 
namespace App\Observers;
 
use App\Models\User;
 
class UserObserver
{
/**
* Handle the User "created" event.
*/
public function created(User $user): void
{
// ...
}
 
/**
* Handle the User "updated" event.
*/
public function updated(User $user): void
{
// ...
}
 
/**
* Handle the User "deleted" event.
*/
public function deleted(User $user): void
{
// ...
}
 
/**
* Handle the User "restored" event.
*/
public function restored(User $user): void
{
// ...
}
 
/**
* Handle the User "forceDeleted" event.
*/
public function forceDeleted(User $user): void
{
// ...
}
}

For example, you can send a notification to someone, notify the admin that the user was created, or inform the user themselves with some welcome email.

In this example, I will log that the user was created with the email.

app/Observers/UserObserver.php:

use App\Models\User;
 
class UserObserver
{
public function created(User $user): void
{
info('User was created: ' . $user->email);
}
 
// ...
}

Register Observers

It's not enough to generate an Observer. We need to register that into the system. Registration can be done in two ways. The first one uses the PHP attribute ObservedBy on the Model.

app/Models/User.php:

use Illuminate\Database\Eloquent\Attributes\ObservedBy;
 
#[ObservedBy(UserObserver::class)]
class User extends Authenticatable
{
// ...
}

Or it can be registered in the AppServiceProvider.

app/Providers/AppServiceProvider.php:

use App\Models\User;
use App\Observers\UserObserver;
 
class AppServiceProvider extends ServiceProvider
{
// ...
 
public function boot(): void
{
User::observe(UserObserver::class);
}
}

In Laravel 10 and below, instead of AppServiceProvider, you would use EventServiceProvider.

If you create a user, there should be a new message in the logs.

storage/logs/laravel.log:

[2024-03-01 12:19:52] local.INFO: User was created: test@test.com

More Methods in Observers

In addition to the methods that are automatically generated when you run the artisan command, you can create methods for the events that Laravel also supports.

For example, created() and updated() are separate methods, but one method is saved(), which will be automatically launched in both cases in the created and updated.

But more useful are methods like creating(). So for all of those created(), updated(), and deleted(), which happen after the record is saved in the database, you can also define creating(), updating(), and deleting(), which would happen before the record is changed in the database. For these methods, the parameter is the same Model.

For example, if you want your user email to be verified automatically.

app/Observers/UserObserver.php:

use App\Models\User;
 
class UserObserver
{
public function updating(User $user): void
{
$user->email_verified_at = now();
}
 
public function created(User $user): void
{
info('User was created: ' . $user->email);
}
 
// ...
}

If you launch the user creation code without specifying the email_verified_at column in the DB, you should still see the column value with the date.