PS. I am aware of $page->getChanges(), but this only gets me access to the new value, and not to the old value.
Best way to watch for changes in models
I want to create an audit trail of changes to our pages, for legal reasons.
So we have a Page model and a PageChange model.
I have a method that is really elegant, using the updating event model to diff every field and log to the DB (see code sample below), using getDirty() and getOriginal().
This is elegant, but flawed, because if the $page->save() method fails, e.g. if the DB complains because of a non-nullable field, or a FK issue, then incorrect PageChange entries will be written.
However using the updated event is too late, because at that point the original value is already overwritten and the dirty() flag is cleared in the Eloquent model.
Can anyone suggest a better method?
(code below)
On our Page model, I have attached an updating event, which will fire a LogPageChange.
App\Models\Page.php:
protected $dispatchesEvents = [
'updating' => PageUpdating::class,
];
This is correctly set up to EventServiceProvider to trigger this:
class LogPageChange
{
public function handle($event)
{
/** @var Page */
$page = $event->page;
/** @var Collection */
$changes = collect($page->getDirty());
/** @var User */
$user = \Auth::user();
$changes->each(
function ($newValue, $diffedField) use ($page, $user) {
PageChange::create([
'user_id' => $user?->id,
'page_id' => $page->id,
'page_card' => $diffedField,
'old_value' => $page->getOriginal($diffedField),
'new_value' => $newValue,
]);
}
);
}
}
Please or to participate in this conversation.