Querying Logs

Every auditable model gets an auditLogs morphMany relationship. You can query it like any Eloquent relationship — filter by event, date range, user, or any other column.

The auditLogs Relationship

// All audit logs for a model
$user->auditLogs;

// As a query builder
$user->auditLogs()->get();

The relationship returns AuditLog model instances ordered by the database default (insertion order).

Filter by Event

// Only updates
$user->auditLogs()->where('event', 'updated')->get();

// Multiple events
$user->auditLogs()->whereIn('event', ['created', 'updated'])->get();

// Custom events only
$user->auditLogs()->whereNotIn('event', [
    'created', 'updated', 'deleted', 'restored', 'forceDeleted', 'retrieved',
])->get();

Filter by Date Range

$user->auditLogs()
    ->where('created_at', '>=', now()->subDays(30))
    ->get();

$user->auditLogs()
    ->whereBetween('created_at', [$start, $end])
    ->get();

Filter by User

Find changes made by a specific user:

$user->auditLogs()->where('user_id', $adminId)->get();

Find changes with no authenticated user (system/console):

$user->auditLogs()->whereNull('user_id')->get();

Filter by Batch

Retrieve all logs from a batch operation:

use GrayMatter\AuditChain\Models\AuditLog;

AuditLog::where('batch_uuid', $batchUuid)->get();

Query Across Models

The AuditLog model can be queried directly for cross-model searches:

use GrayMatter\AuditChain\Models\AuditLog;

// All audit logs for a model type
AuditLog::where('auditable_type', 'App\\Models\\Order')->get();

// Recent activity across all models
AuditLog::where('created_at', '>=', now()->subHour())
    ->orderByDesc('created_at')
    ->get();

// All changes by a specific user
AuditLog::where('user_id', $userId)
    ->orderByDesc('created_at')
    ->get();

Accessing Values

Each AuditLog has these useful attributes:

$log = $user->auditLogs()->latest('created_at')->first();

$log->event;                  // 'updated'
$log->old_values;             // ['email' => 'old@example.com']
$log->new_values;             // ['email' => 'new@example.com']
$log->user_id;                // 1
$log->ip_address;             // '192.168.1.1'
$log->user_agent;             // 'Mozilla/5.0 ...'
$log->batch_uuid;             // 'a1b2c3d4-...'
$log->context;                // ['source' => 'admin_panel']
$log->personal_data_accessed; // ['email']
$log->created_at;             // Carbon instance
$log->hash;                   // SHA-256 hash (full mode) or null (light mode)

The old_values, new_values, personal_data_accessed, and context columns are automatically cast to arrays.

Inverse Relationship

Get the parent model from an audit log:

$log->auditable; // Returns the User, Order, etc.

This is a standard morphTo relationship, so the parent model type and ID are resolved automatically.

Pagination

For large audit trails, paginate as you would with any Eloquent query:

$user->auditLogs()
    ->orderByDesc('created_at')
    ->paginate(25);