laravel-auditing: Audits on custom pivot models broken in latest release

Q A
Bug? yes
New Feature? no
Framework Laravel
Framework version 6.4.0
Package version 9.3.2
PHP version 7.2.21

Actual Behaviour

When auditing custom pivot models that have autoincrementing IDs, the audit event errors with a Column 'auditable_id' cannot be null error

Expected Behaviour

Pivot model data saved to audits table

Steps to Reproduce

On a clean Laravel 6.4 application, create two models related with a many-to-many relationship, using a custom intermediate table model that has an auto-incrementing primary key. With version 9.3.2 of the Laravel-Auditing package, any changes in the relationship will result in an error about the auditable_id value being null. Downgrading to version 9.3.1 doesn’t see this error.

Possible Solutions

Version 9.3.2 was an intended bugfix for non-integer primary keys on audited models, I suggest re-evaluating that pull request. I think this could be worked-around by extending the Audit model and re-adding the auditable_id cast, but that would re-break whatever PR #550 was intended to fix.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 5
  • Comments: 21

Most upvoted comments

A fix / workaround for this is already included in the docs: https://laravel-auditing.com/guide/audit-custom.html#example-related-attributes

Instead of attaching the Auditable classes to your Pivot Tables, you instead need to change your attach() and detatch() methods. You now call the attach() on the original model as auditAttach($relationship), and you don’t call the relationship() method on the model.

Old Method:

$user->posts()->detach($post);

New Method:

$user->auditDetach('posts', $post);

@sudeerax My pivot table has an incrementing primary key id,

public function students()
    {
        return $this->belongsToMany(Student::class)
                    ->using(CourseStudent::class)
                    ->withPivot([
                        'id',
                        'percent_grade',
                        'date',
                        'sales_person_id',
                        'sales_value',
                    ])
}

When I added id to the list of fields in withPivot, on both the courses model, and the students model, the issue went away. I also have public $incrementing = true; on the CourseStudent pivot model but I dont think that made a difference.

Hello, i use this trait

trait PivotAuditable
{
    use Auditable;

    public function transformAudit(array $data): array
    {
        $isEventDeleted = Arr::equalValue($data, 'event', 'deleted');
        $isHasNotAuditableId = Arr::equalValue($data, 'auditable_id', NULL);

        if ($isEventDeleted && $isHasNotAuditableId) {
            $where = [];
            foreach (Arr::get($data, 'old_values', []) as $key => $value)
                $where[$key] = $value;

            tap(self::where($where)->get(self::getKeyName()), function($id) use (&$data) {
                if ($id)
                    $data['auditable_id'] = $id;
                });
            }

            return $data;
    }
}

Laravel 8.83.18 Laravel auditing 13.0.3

The Detach issue still exists… the package really feels abandoned with the broken documentation

Just adding public $incrementing = true on the pivot model (with an auto-incrementing id column) was enough to get this to work with attach() for me. No need to add the id to the ->withPivot() array.

Still throws an error on detach(), though. I think this is due to the delete event for pivot models not having the id when triggered through detach, which seems to maybe be a Laravel issue. So, the workarounds mentioned previously (either deleting the pivot model instance directly or overriding getKey to return a dummy key) are needed.

edit: Since this issue is specific to writing the audit, a safer alternative workaround to overridding getKey(), which might have unintended consequences, is to use transformAudit(), e.g.:

public function transformAudit(array $data): array
{
    // The detach model event doesn't properly include the pivot model id,
    // so we need this workaround for now.
    $data['auditable_id'] = $data['auditable_id'] ?? 0;

    return $data;
}

(I’m using laravel 8 and laravel-auditing 12.)

@AharonFeinstein thanks for the tip. This works well for me when I call attach, but not when I call detach. It looks like the id attribute isn’t included in my pivot model even when I call withPivot([ 'id', ... ]) in the parent model. Can please you confirm if detach works for you or not?