Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/HypathStack/model-scribe/llms.txt

Use this file to discover all available pages before exploring further.

ScribeLog is an Eloquent model in HypathBel\ModelScribe\Models that represents a single audit log record written by a ModelScribe driver. Each row in the audit table corresponds to one ScribeLog instance and captures the event type, the actors involved, a JSON properties payload, contextual HTTP metadata, and optional grouping fields such as log name, tags, and a batch UUID.
use HypathBel\ModelScribe\Models\ScribeLog;

Database Columns

The table name resolves dynamically via getTable() (see below), defaulting to model_scribe_logs.
ColumnTypeNullableDefaultDescription
idbigintNoauto-incrementPrimary key
log_namestringNo'default'Routing / grouping key set by $auditLogName
eventstringNoThe event type; one of the ScribeEvent string values
descriptiontextYesnullOptional human-readable description of the event
causer_typestringYesnullPolymorphic morph type for the acting model
causer_idbigint / stringYesnullPolymorphic morph ID for the acting model
subject_typestringYesnullPolymorphic morph type for the audited model
subject_idbigint / stringYesnullPolymorphic morph ID for the audited model
propertiesjsonYesnullAttribute snapshot; contains old and attributes keys
urltextYesnullFull URL of the HTTP request that triggered the event
ip_addressinetYesnullClient IP address at the time of the event
user_agentstringYesnullClient User-Agent string at the time of the event
batch_uuiduuidYesnullGroups related entries created in the same request cycle
tagsjsonYesnullArray of string tags
created_attimestampNoStandard Eloquent timestamp
updated_attimestampNoStandard Eloquent timestamp

Casts

The following columns are automatically cast by Eloquent when reading from the database:
PropertyCastNotes
propertiesarrayDeserialized from JSON; contains 'old' and 'attributes' sub-keys
tagsarrayDeserialized from JSON; an array of strings

Relationships

subject()

Returns the audited Eloquent model — the entity that was acted upon.
public function subject(): MorphTo
$log = ScribeLog::find(1);

// Resolve the polymorphic subject
$invoice = $log->subject; // e.g. an App\Models\Invoice instance

causer()

Returns the Eloquent model representing the actor — typically the authenticated user who triggered the event.
public function causer(): MorphTo
$log = ScribeLog::find(1);

// Resolve the causer
$user = $log->causer; // e.g. an App\Models\User instance

Query Scopes

All scopes follow Laravel’s local scope convention. Call them as static methods on the model class (without the scope prefix).
forSubject
scope
Filters entries to those where subject_type and subject_id match the given model. Use this to retrieve the full audit trail of a specific record.
// All audit entries for a particular invoice
$logs = ScribeLog::forSubject($invoice)->latest()->get();
forCauser
scope
Filters entries to those where causer_type and causer_id match the given model. Use this to see every action a specific user has taken.
// Everything the current user has done
$logs = ScribeLog::forCauser($request->user())->latest()->get();
forEvent
scope
Filters entries to a specific event type string (e.g. 'updated', 'deleted').
// Only deletion events across all models
$deletions = ScribeLog::forEvent('deleted')->latest()->get();

// Combine with forSubject to scope further
$updates = ScribeLog::forSubject($order)->forEvent('updated')->get();
inLog
scope
Filters entries by log_name. Useful when multiple model types write to named log channels.
// All entries in the 'orders' log channel
$orderLogs = ScribeLog::inLog('orders')->latest()->paginate(25);

Accessors

These computed properties extract the two main sub-keys from the properties JSON column, saving you from manually accessing the raw array.
new_attributes
array
Returns the model attributes after the event was applied, sourced from $this->properties['attributes'] ?? []. Populated for created and updated events.
$log = ScribeLog::forSubject($invoice)->forEvent('updated')->latest()->first();

// ['amount' => 500, 'status' => 'paid']
$after = $log->new_attributes;
old_attributes
array
Returns the model attributes before the event, sourced from $this->properties['old'] ?? []. Populated for updated and deleted events.
// ['amount' => 250, 'status' => 'pending']
$before = $log->old_attributes;

getTable() Override

ScribeLog overrides the default Eloquent getTable() method to support dynamic table-name resolution:
public function getTable(): string
{
    return $this->table ?? config('model-scribe.drivers.database.table', 'model_scribe_logs');
}
If the table property has been set explicitly on the model instance, that value takes precedence. Otherwise, the table name is read from config('model-scribe.drivers.database.table'), falling back to 'model_scribe_logs'. This means you can change the audit table name in your configuration without touching any model classes or query code.

Putting It All Together

use HypathBel\ModelScribe\Models\ScribeLog;

// Full audit trail for a specific order, newest first
$trail = ScribeLog::forSubject($order)
    ->with(['causer'])
    ->latest()
    ->get();

foreach ($trail as $entry) {
    echo sprintf(
        '[%s] %s by %s',
        $entry->event,
        $entry->description ?? 'no description',
        optional($entry->causer)->name ?? 'system',
    );

    if ($entry->event === 'updated') {
        // Show what changed
        $changes = array_diff_assoc($entry->new_attributes, $entry->old_attributes);
        dump($changes);
    }
}
The properties column stores a raw JSON blob. Always access attribute snapshots through the new_attributes and old_attributes accessors rather than indexing into $log->properties directly — the accessors provide safe null-coalescing defaults.
Combine multiple scopes with standard Eloquent query methods to build precise audit queries without writing raw SQL:
ScribeLog::inLog('invoices')
    ->forEvent('updated')
    ->forCauser($admin)
    ->whereBetween('created_at', [$start, $end])
    ->latest()
    ->paginate(50);

Build docs developers (and LLMs) love