Eloquent: How to Check if a Model Attribute Changed

Updated: January 16, 2024 By: Guest Contributor Post a comment

Introduction

Eloquent, the ORM (Object Relational Mapper) used in Laravel, makes it incredibly easy to interact with a database using an expressive syntax. Among its many features is the ability to detect if a model’s attribute has changed. This can be particularly useful when you want to perform certain actions in response to changes or to simply track the changes. This tutorial will guide you through various ways to check if a model attribute has changed using Eloquent.

Prerequisites

  • Basic understanding of Laravel and Eloquent ORM
  • A Laravel application
  • A database with at least one table and a corresponding Eloquent model

Using the isDirty() and wasChanged() Methods

Let’s start with a basic example. Imagine we have a User model and we want to check if the name attribute has changed after updating:

<?php

$user = User::find(1);
$user->name = ‘Jane Doe’;

if ($user->isDirty('name')) {
    echo 'Name has been changed.';
}

$user->save();

if ($user->wasChanged('name')) {
    echo 'Name was changed during the last save.';
}
?>

isDirty() will return true if the name was updated but not yet persisted to the database. wasChanged() will return true once the changes have been saved to the database.

Checking Changes for Multiple Attributes

To check if multiple attributes have changed, you can pass an array of attribute names to the isDirty() and wasChanged() methods:

<?php

$user->name = 'Jane Doe';
$user->email = '[email protected]';

if ($user->isDirty(['name', 'email'])) {
    echo 'Name or email has been changed.';
}

$user->save();

if ($user->wasChanged(['name', 'email'])) {
    echo 'Name or email was changed during the last save.';
}
?>

If either one of the attributes is dirty, the method will return true.

Working with Original Attributes

Sometimes you might want to know the original value of an attribute before it was changed. Eloquent provides the getOriginal() method:

<?php

$user->name = 'Jane Doe';
$originalName = $user->getOriginal('name');

echo 'The original name was ' . $originalName . '<br/>';

$user->save();

// Output: The original name was John Doe
?>

This will give you the value that was initially fetched from the database, not the updated value that is currently set on the model.

Advanced Scenario: Observers and Events

Eloquent also allows you to define Observers and Events to detect changes on a model and act accordingly. You can set up an observer for the User model that listens to the updating event:

<?php

use App\Models\User;
use Illuminate\Support\Facades\Event;

Event::listen('eloquent.updating: '.User::class, function ($user) {
    if ($user->isDirty('name')) {
        // Perform action if name attribute is changed.
    }
});
?>

Observers allow you to organize all of your event logic in one place, providing a cleaner approach for complex scenarios.

Conclusion

Throughout this article, we explored several methods to check if a model attribute has changed using Eloquent in Laravel. Whether you require a simple check with isDirty(), wasChanged(), or need to utilize observers for more elaborate cases, Laravel’s Eloquent ORM equips you with the necessary tools for maintaining clean and effective model state checks.

Understanding and utilizing Eloquent’s built-in mechanisms for detecting changes in model attributes can vastly enhance the efficiency in which one can handle data mutations within a Laravel application.