a2zwebltd/auditable-relations
Auditable Relations extends Laravel auditing to relationship changes, so attaches, detaches, syncs, and related model updates are captured automatically. Get a clear, queryable history of who changed what and when, without wiring audit logic into every relation by hand.
Install and configure Laravel Auditing first, then add this package:
composer require owen-it/laravel-auditing
php artisan vendor:publish --provider="OwenIt\Auditing\AuditingServiceProvider"
php artisan migrate
composer require a2zwebltd/auditable-relations
Add Laravel Auditing's Auditable trait/contract to every model you want audited, plus this package's relationship-auditing trait (the exact trait and namespace are in the README and in resources/boost/guidelines/core.blade.php). This package does not replace Laravel Auditing's audits table or config — it plugs relationship operations into it.
First use case: role/permission or team-membership changes. Instead of:
$user->roles()->attach($role);
do:
$user->roles()->auditableRelation()->attach($role);
The attach and its pivot data are written to audits alongside your normal model audits, so you can show "Alice was granted Editor on 12 March" in an admin UI.
Look first at:
resources/boost/guidelines/core.blade.php — the shortest authoritative usage rules.Auditor resolver, audit config, pruning, and the audits schema.auditableRelation(). It keeps coverage consistent and makes the audited path greppable.attach, detach, sync, syncWithoutDetaching, toggle, and updateExistingPivot. The package handles the pivot event, while Laravel Auditing handles the audit record.AuditablePivot / AuditableMorphPivot, or use HandlesAuditablePivot on your own pivot model to audit direct save()/delete() calls inside a transaction.withPivot(), withTimestamps(), using(), as(), and wherePivot() survive when invoked on the relationship; build the query normally and wrap it at the point of mutation.MorphToMany::attach() is audited as of v1.2.0 — include taggables/comments in coverage if relevant.audits filtered by auditable_type/auditable_id, then join the user_id/user_type fields Laravel Auditing writes for "who changed what" screens. Filter by audit event to separate relation changes from model changes.DB::transaction() so domain changes and audit rows commit or roll back together.audits row with the expected event and new_values. Cover both attach and detach, and the attach half of toggle() (a v1.2.0 fix). Mirror the package's Pest style.$user->roles()->attach($id) bypasses the package entirely. This is the most common "why is my audit missing?" cause — enforce it via a repository layer or a static-analysis rule.^1.2. Earlier versions dropped pivot constraints, swapped custom using() pivots for AuditablePivot, missed MorphToMany::attach(), and only audited half of toggle().SELECTs per operation and full related-model snapshots in new_values. High-churn pivots (tags, followers, likes) will bloat the audits table. Use Laravel Auditing's retention/cleanup command and exclude noisy relations.Auditor resolver. Without it, console commands and queued jobs record no user. If audit queuing is enabled, tests may see delayed rows — use a sync queue in the test environment.$auditExclude / $auditInclude and keep secrets out of pivot columns.auditableRelation() actually used, morph map correct, queue config inspected.Audit::create() or spatie/laravel-activitylog) if maintenance stalls.transformAudit() on your audited models to tag or reshape audit entries.How can I help you explore Laravel packages today?