Mahamudul Hasan Rubel
HomeBlogCoursesAboutProjectsSkillsExperiencePhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • Blog
  • Courses
  • About
  • Projects
  • Skills
  • Experience
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

Subscribe to the newsletter

Get new articles and course lessons delivered to your inbox. No spam, unsubscribe anytime.

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 24 of the Intermediate Laravel: Real-World Application Patterns course
LaravelJune 26, 20263 min read

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.

laraveleloquentobserversarchitecturebackendphp

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:

Bash
php 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:

PHP
namespace 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.

  1. Create a ProjectObserver to handle the updated event.
  2. Inside the updated method, log a message whenever a project's name attribute changes.
  3. Hint: Use $project->isDirty('name') to check if the column was modified before logging.
  4. Register the observer in the AppServiceProvider and verify the log output in storage/logs/laravel.log after 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 use Task::where('status', 'pending')->update(['status' => 'done']), the updated observer 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 the updated method, you will trigger the updated event again, causing an infinite loop. Always use updateQuietly() 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 boot method 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.

Previous lessonReal-time Notifications with BroadcastingNext lesson Implementing Policies for Authorization
Back to Blog

Similar Posts

LaravelJune 26, 20263 min read

Strategy Pattern for Business Rules in Laravel

Stop writing massive if-else chains for business logic. Learn how to implement the Strategy pattern in Laravel to keep your services clean and extensible.

Read more
LaravelJune 26, 20264 min read

Using Value Objects: Encapsulating Domain Logic in Laravel

Learn how to use Value Objects in Laravel to eliminate primitive obsession, encapsulate attribute logic, and improve domain clarity in your models.

Part of the course

Intermediate Laravel: Real-World Application Patterns

intermediate · Lesson 24 of 58

  1. 1

    Architecting for Maintainability

    3 min
  2. 2

    Implementing the Service Layer

    3 min
  3. 3

    Repository Pattern Fundamentals

    3 min
Read more
LaravelJune 26, 20263 min read

Project Structure for Large Applications: Domain-Driven Laravel

Stop drowning in a massive 'App' folder. Learn to use domain-driven architecture to organize your Laravel project for long-term scalability and sanity.

Read more
  • 4

    Project Board Domain Modeling

    3 min
  • 5

    Advanced Eloquent Scopes and Accessors

    4 min
  • 6

    Service-Oriented Task Management

    3 min
  • 7

    REST API Fundamentals with Sanctum

    3 min
  • 8

    Resource Controllers and API Responses

    3 min
  • 9

    Handling API Validation and Form Requests

    3 min
  • 10

    Implementing Middleware for API Security

    4 min
  • 11

    Database Transactions for Data Integrity

    3 min
  • 12

    Error Handling and Global Exceptions

    3 min
  • 13

    Introduction to Laravel Events and Listeners

    3 min
  • 14

    Asynchronous Processing with Queues

    4 min
  • 15

    Job Chaining and Batching

    3 min
  • 16

    Feature Testing Fundamentals

    4 min
  • 17

    Mocking Services and Repositories in Tests

    3 min
  • 18

    Testing Events and Jobs

    3 min
  • 19

    Database Factories and Seeding

    3 min
  • 20

    API Versioning Strategies

    4 min
  • 21

    Advanced Request Filtering and Sorting

    3 min
  • 22

    Handling File Uploads in REST APIs

    3 min
  • 23

    Real-time Notifications with Broadcasting

    3 min
  • 24

    Using Observers for Model Lifecycle Hooks

    3 min
  • 25

    Implementing Policies for Authorization

    3 min
  • 26

    Customizing Authentication Guards

    3 min
  • 27

    Rate Limiting API Endpoints

    4 min
  • 28

    Eloquent Performance Optimization

    4 min
  • 29

    Caching Strategies for Performance

    4 min
  • 30

    Using Traits for Code Reuse

    3 min
  • 31

    Advanced Dependency Injection with Service Providers

    3 min
  • 32

    Command Line Tools with Artisan

    3 min
  • 33

    Scheduled Tasks and Cron Jobs

    3 min
  • 34

    Integrating Third-Party Services

    3 min
  • 35

    Handling Webhooks

    3 min
  • 36

    Logging and Monitoring

    3 min
  • 37

    Database Migrations Best Practices

    3 min
  • 38

    Advanced Testing: Integration Tests

    4 min
  • 39

    Testing API Authentication

    4 min
  • 40

    Code Quality and Static Analysis

    3 min
  • 41

    Project Structure for Large Applications

    3 min
  • 42

    Environment and Configuration Management

    3 min
  • 43

    Deploying Laravel Applications

    4 min
  • 44

    Database Indexing Strategies

    4 min
  • 45

    Using Value Objects

    4 min
  • 46

    Strategy Pattern for Business Rules

    3 min
  • 47

    Advanced Queue Monitoring

    3 min
  • 48

    Building a Search API

    3 min
  • 49

    Handling Concurrency and Race Conditions

    4 min
  • 50

    API Documentation with OpenAPI

    3 min
  • 51

    Testing with Test Doubles

    3 min
  • 52

    Implementing Multi-Tenancy

    4 min
  • 53

    Refactoring Legacy Code

    4 min
  • 54

    Using Middleware for Feature Flags

    3 min
  • 55

    Building Reusable Packages

    4 min
  • 56

    Performance Profiling

    3 min
  • 57

    Secure API Design

    3 min
  • 58

    Event Sourcing Concepts

    4 min
  • View full course