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
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})");
}
}
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)