Using Observers for Model Lifecycle Hooks in Laravel
Learn how to use Eloquent observers to centralize model lifecycle logic. Stop cluttering services and keep your project board events clean and maintainable.
Previously in this course, we explored Asynchronous Processing with Queues in Laravel to handle heavy lifting in the background. While queues manage deferred tasks, sometimes you need to trigger logic immediately when a database record changes. This is where model observers come into play.
Observers allow you to group all the event listeners for a particular Eloquent model into a single class. Instead of scattering Task::created() hooks across your Service Layer, you centralize that orchestration in one place.
Understanding the Eloquent Lifecycle
Eloquent models fire several events during their lifecycle: retrieved, creating, created, updating, updated, saving, saved, deleting, deleted, restoring, and restored.
When we talk about the lifecycle, we refer to the sequence of database operations. For instance, when you call $task->save(), Eloquent fires events that allow you to inject custom logic before the SQL is executed (e.g., creating or updating) or after the change is committed (e.g., created or updated).
Creating and Registering Observers
Let’s evolve our project board. We want to ensure that every time a Task is deleted, we also clean up any associated activity logs or temporary file references. Instead of adding this to our Service-Oriented Task Management, we’ll use an observer.
1. Generate the Observer
Use the Artisan command to create the observer class:
Bashphp artisan make:observer TaskObserver --model=Task
This creates app/Observers/TaskObserver.php.
2. Implement Lifecycle Methods
Open the file and add your logic. Observers are just plain classes where method names match the event they handle:
PHPnamespace App\Observers; use App\Models\Task; use Illuminate\Support\Facades\Log; class TaskObserver { public function created(Task $task): void { Log::info("Task {$task->id} was created by user {$task->user_id}"); } public function deleted(Task $task): void { #6A9955">// Clean up related assets $task->attachments()->delete(); } }
3. Register the Observer
To make Laravel aware of your observer, you must register it in your AppServiceProvider.
PHP#6A9955">// app/Providers/AppServiceProvider.php use App\Models\Task; use App\Observers\TaskObserver; public function boot(): void { Task::observe(TaskObserver::class); }
Hands-on Exercise
Your project board needs an audit trail.
- Create a
ProjectObserverto handle theupdatedevent. - Inside the
updatedmethod, log a message whenever a project'snameattribute changes. - Hint: Use
$project->isDirty('name')to check if the column was modified before logging. - Register the observer in the
AppServiceProviderand verify the log output instorage/logs/laravel.logafter updating a project via your API.
Common Pitfalls
- Mass Assignment/Updates: Observers only fire when you use Eloquent models (e.g.,
$task->delete()or$task->save()). If you useTask::where('status', 'pending')->update(['status' => 'done']), theupdatedobserver will not fire. Eloquent performs these as direct database queries for performance. - Infinite Loops: Be careful modifying the model inside an observer. If you call
$task->save()inside theupdatedmethod, you will trigger theupdatedevent again, causing an infinite loop. Always useupdateQuietly()if you need to modify the model without triggering further events. - Over-Engineering: Observers are powerful, but don't put complex business logic in them. They are best for "side effects." If the logic involves complex dependencies, keep it in a Service class and call that service from the observer.
Recap
We've moved from manual event hooking to a centralized, clean architecture using observers.
- Observers allow you to group lifecycle hooks for specific models.
- Registration happens in the
bootmethod of your Service Provider. - Lifecycle events provide hooks for both before and after database persistence.
By keeping your models clean and your side effects isolated, you ensure your project board remains maintainable as it scales.
Up next: We’ll look at Implementing Policies for Authorization to ensure users only interact with tasks they own.
Work with me

Laravel REST API Development
Clean, secure, well-documented Laravel REST APIs — the backend engine for your app, mobile client, or SaaS. Built by an API specialist.

FilamentPHP Admin Panel & Dashboard Development
A powerful admin panel for your Laravel app — built with FilamentPHP so you can manage everything without touching the database.