$ lexprog.com

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

[February 11, 2025] Eloquent ORM

Eloquent Touching: Parent Timestamps

Eloquent Touching: Parent Timestamps

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

Eloquent Touching: Parent Timestamps

Tip: $touches for Parent Updates

class Comment extends Model
{
    protected $touches = ['post'];
}

When a comment is saved, the parent post's updated_at is updated too.

Gotcha: $touches Works on Create and Update

Both creating and updating a child model touches the parent.

Tip: withoutTouching() to Skip

Comment::withoutTouching(function () {
    $comment->update(['body' => 'New text']);
});

Prevents parent timestamp updates during bulk operations.

Gotcha: Multiple Touches

protected $touches = ['post', 'author'];

Touches all listed relations. Can cause cascading timestamp updates.

Tip: Manual Touching

$post->touch();

Updates updated_at without changing any other data.

Gotcha: updated_at Not Updated on update()

If no attributes actually change, updated_at is not updated. Use touch() to force it.

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

The touches property on relationships is convenient for cache invalidation, but it creates cascading database writes that can surprise you. I've seen a single model update trigger 15 updated_at changes across related models because of touches chains. When this happens on every request in a high-traffic endpoint, the database write load increases dramatically. Use touches sparingly and only for relationships where timestamp accuracy genuinely matters.

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

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