Troubleshooting
This is a compilation of common problems and their respective solutions and/or workarounds.
Auditing does not work
You followed the documentation to the letter and yet, Audit
records are not being created?
Builder vs. Eloquent
Bear in mind that this package relies on Eloquent events and if they don't fire, an Audit
cannot be created.
The most common mistake is performing an update
or delete
using a Builder
instance, rather than an using an Eloquent Model
.
Using the Builder
won't trigger an Audit
:
Article::where('id', $id)->update($data);
But using Eloquent
will:
Article::find($id)->update($data);
Console/CLI and Jobs
Eloquent events fired from a Job or from the console (i.e. migrations, tests, commands, Tinker, ...), WILL NOT be audited by default.
Please refer to the General Configuration for more information.
Attributes are considered modified, when they're not
False positives cause Audit records to be created. This happens when a model with boolean/date attributes gets updated, regardless of change in those attributes.
TIP
This behaviour has been fixed in Laravel 5.5+, but it's still present in older versions.
The internal data of the Eloquent model will be as follows:
In the $attributes array attribute:
true
staystrue
false
staysfalse
YYYY-MM-DD
staysYYYY-MM-DD
In the $original array attribute:
true
becomes1
false
becomes0
YYYY-MM-DD
becomesYYYY-MM-DD 00:00:00
This makes the getDirty()
and isDirty()
methods to consider wrongful attribute changes when comparing data.
TIP
For Laravel versions prior to 5.5, use this trait, courtesy of Peter Klooster!
Other discussions about this subject.
Argument 1 passed to Illuminate\Database\Eloquent\Model::serializeDate() must implement interface DateTimeInterface, null given
This might happen in version 4.1.x, because the updated_at
column values in the audits
table are set to NULL
.
After upgrading the table schema for 4.1.x, don't forget to set the updated_at
values to match the ones from created_at
.
Read the Upgrading documentation for more details.
Empty old/new values being audited
An Audit
record is more than just old and new values.
There's metadata like event
, user_*
, url
, ip_address
, user_agent
and tags
, which in some cases is more than enough for accountability purposes.
Still, if you don't want to keep track of such information when the old_values
and new_values
are empty, register the following observer in the Audit
model's boot()
method:
Audit::creating(function (Audit $model) {
if (empty($model->old_values) && empty($model->new_values)) {
return false;
}
});
INFO
Keep in mind that the old_values
and new_values
of a retrieved
event, will always be empty!
PHP Fatal error: Maximum function nesting level of '512' reached, aborting!
This error happens when an Audit
is being created for a retrieved
event on a User
model. It boils down to the UserResolver
, retrieving a User
record, which will fire a new retrieved
event, leading to a new resolve cycle and so on.
To avoid this, make sure the User
model isn't configured for retrieval audits, like so:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use OwenIt\Auditing\Contracts\Auditable;
class User extends Model implements Auditable
{
use \OwenIt\Auditing\Auditable;
protected $auditEvents = [
'created',
'updated',
'deleted',
'restored',
];
// ...
}
AuditableTransitionException: Expected Auditable id 123, got 123 instead
When this exception is thrown and the expected and current ids in the message are the same, it means that there's a casting problem.
To overcome it, make sure the auditable_id
is included in the $casts
property, like so:
protected $casts = [
'old_values' => 'json',
'new_values' => 'json',
'auditable_id' => 'integer',
];
INFO
From version 8.0.3, the Audit
model now includes the auditable_id
in the $casts
property, defaulting to integer
. Change it to string
if you are using UUID.
A description of this issue can be found here.
Attribute accessors and modifiers are not applied to SoftDeleted models
Because not everyone uses the SoftDeletes
trait, the Audit
relationships (Auditable
and User
) will return null
by default, if any of those related records has been soft deleted.
To overcome this problem, the relation methods in the Audit
model must be updated to include trashed models:
/**
* {@inheritdoc}
*/
public function auditable()
{
return $this->morphTo()->withTrashed();
}
/**
* {@inheritdoc}
*/
public function user()
{
return $this->morphTo()->withTrashed();
}
TIP
A custom Audit
model needs to be created with the above methods. Don't forget to update the Audit
implementation in your configuration!