$ lexprog.com

// notes from an old coder -- php, databases, and the occasional rant

[November 03, 2025] Eloquent ORM

Eloquent Get Attribute: Override Behavior

Eloquent Get Attribute: Override Behavior

────────────────────────────────────────────────────────

Eloquent Get Attribute: Override Behavior

Tip: Override getAttribute()

public function getAttribute($key)
{
    if ($key === 'display_name') {
        return $this->first_name . ' ' . $this->last_name;
    }
    return parent::getAttribute($key);
}

Gotcha: getRawOriginal() for Database Values

$post->getRawOriginal('title');

Returns the raw database value, bypassing accessors and casts.

Tip: isDirty() for Change Detection

if ($post->isDirty('title')) {
    // Title changed
}

Gotcha: getChanges() After Save

$post->save();
$changes = $post->getChanges();

Returns only the attributes that were actually changed.

Tip: wasChanged() After Save

$post->update(['title' => 'New']);
if ($post->wasChanged('title')) {
    // Title was actually updated
}

Gotcha: getAttribute() vs Direct Access

$post->title calls getAttribute('title'). Override carefully to avoid breaking casts.

Tip: Use cursor() for Memory-Neutral Iteration

When exporting 100K rows, get() loads everything into memory. cursor() uses yield and keeps memory flat regardless of row count. Perfect for artisan commands.

Tip: whereHas() vs load() — Two Different Things

whereHas() filters the parent query by relationship existence. load() eager-loads relationships AFTER the query. Mixing them up is a common source of logic bugs.

Gotcha: withCount() Adds a Subquery

withCount('comments') runs a correlated subquery on every row. On large tables, this can be slower than a separate query. Profile before relying on it.

Senior Insight

Overriding getAttribute() on a model is a powerful way to customize attribute access, but it's also a performance trap. Every model hydration calls getAttribute() for every column, so a slow implementation affects every query. I learned this the hard way when a custom getAttribute() that made an API call brought the application to its knees. Use accessors instead of overriding getAttribute(), and keep overrides limited to simple transformations.

Source: Laravel Docs (https://laravel.com/docs/eloquent), Laravel News (https://laravel-news.com/), Freek.dev (https://freek.dev/tags/eloquent)

────────────────────────────────────────────────────────
<-- back to posts