4

I'm building an audit system in my application, and I want to compare an Eloquent Model attribute changes after save() method. Here's an example of what I need:

$person = Person::find(1); //Original data: $person->name -> 'Original name', $person->age -> 22
$person->name = 'A new name';
$person->age = 23;
$person->save();

//At this point, I need to get an array like this (only with the attributes that have changed):
[
  'age' => ['old' => 22, 'new' => 23],
  'name' => ['old' => 'Original name', 'new' => 'A new name']
]

I know Eloquent already has some functions like isDirty(), getDirty() and getChanges(), however this methods only return the new values, and I need to get the old and the new values to store in my audit table.

Is there any way to do this without need to "clone" my variables and then compare it to get the changes?

Fantasmic
  • 1,122
  • 17
  • 25

4 Answers4

3

Before saving your model you can access the original (old) attribute values like: $person->original.

Furthermore you can call: $person->getChanges() to get all attributes that changed.

Aless55
  • 2,652
  • 2
  • 15
  • 26
0

Before the Save() function and before overwriting the variables on lines 2 and 3, you can get old data by doing this:

$oldName = $person->name;
$oldAge = $person->age;

And then, after saving, you can insert your values in an array, like this:

$values = array(
"oldName" => $oldName,
"newName" => "New Name",
"oldAge" => $oldAge,
"newAge" => "New Age",
);

So you can get values from the array by doing:

echo $values["oldName"];
echo $values["newAge"];
...
0

You can clone the newly retrieved model before making the changes. Something along the line of

$person = Person::find(1); 
$original_person = cone $person;

// update the person object
// ...
$person->save();

You can proceed to construct your array like so:

[
  'age' => ['old' => $original_person->age, 'new' => $person->age],
  'name' => ['old' => $original_person->name, 'new' => $person->name]
]
emman
  • 1
-1

You can do this within updated() boot function in the model class

class Mymodel extends Model
{
    public static function boot()
    {
        parent::boot();

        self::updated(function ($model) {
            var_dump($model->original);
            var_dump($model->getChanges());
            // Traverse the changed array and save with original values
        });
    }
}
Sadee
  • 3,010
  • 35
  • 36