DEV Community

Dhiecoderweb
Dhiecoderweb

Posted on Originally published at dhiecoderweb.com

How to Use Model Observers in Laravel

Have you ever needed to run certain code every time a model is saved, updated, or deleted? For example, automatically creating an activity log, sending a notification, or clearing the cache. The naive way is to write it in every controller, but this violates the DRY (Don't Repeat Yourself) principle. The solution is a Model Observer — a class that "watches" Eloquent lifecycle events and reacts automatically.

What Are Eloquent Events?

Eloquent fires the following events during a model's lifecycle:

  • creating / created — before and after INSERT.
  • updating / updated — before and after UPDATE.
  • saving / saved — before and after CREATE or UPDATE.
  • deleting / deleted — before and after DELETE.
  • restoring / restored — for soft deletes, before and after restore.
  • retrieved — after the model is retrieved from the database.

Creating an Observer

Create an observer using Artisan:

php artisan make:observer ProductObserver --model=Product
Enter fullscreen mode Exit fullscreen mode

The file is created at app/Observers/ProductObserver.php:

<?php

namespace App\Observers;

use App\Models\Product;
use Illuminate\Support\Facades\Log;

class ProductObserver
{
    public function creating(Product $product): void
    {
        // Automatically fill the slug before saving
        if (empty($product->slug)) {
            $product->slug = \Str::slug($product->name);
        }
    }

    public function created(Product $product): void
    {
        Log::info("New product created: {$product->name} (ID: {$product->id})");
    }

    public function updating(Product $product): void
    {
        // Update the slug if the name changes
        if ($product->isDirty('name')) {
            $product->slug = \Str::slug($product->name);
        }
    }

    public function updated(Product $product): void
    {
        // Clear the cache related to this product
        cache()->forget("product_{$product->id}");
        Log::info("Product updated: {$product->name}");
    }

    public function deleting(Product $product): void
    {
        // Delete all related images before the product is deleted
        foreach ($product->images as $image) {
            \Storage::disk('public')->delete($image->path);
            $image->delete();
        }
    }

    public function deleted(Product $product): void
    {
        Log::warning("Product deleted: {$product->name} (ID: {$product->id})");
    }
}
Enter fullscreen mode Exit fullscreen mode

This is only part of the article. For the full discussion, with examples and step-by-step details, you can read it on the original source:

How to Use Model Observers in Laravel

More programming tutorials and developer tools are also available at dhiecoderweb.com.

Top comments (0)