Eloquent Relationship Caching
Eloquent Relationship Caching
Eloquent Relationship Caching
Tip: Relations Are Cached
$post->author; // Query 1
$post->author; // No query - cached
Gotcha: load() Overwrites Cache
$post->load('author'); // Reloads and caches
Tip: Check if Loaded
if ($post->relationLoaded('author')) {
// Already loaded
}
Gotcha: setRelation() for Manual Cache
$post->setRelation('author', $user);
Tip: unsetRelation() to Clear
$post->unsetRelation('author');
Forces reload on next access.
Gotcha: push() and Relations
push() saves the model AND its loaded relations. Unloaded relations are ignored.
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
Caching relationship results is a common performance optimization, but it introduces consistency challenges. I've seen cached relationship data serve stale results after the underlying data changed because the cache key didn't include the model's updated_at timestamp. I always include a model-relevant invalidation key (like updated_at timestamp or a version counter) in cache keys for relationship data, and I invalidate cached relationships when the parent model is saved.
Source: Laravel Docs (https://laravel.com/docs/eloquent), Laravel News (https://laravel-news.com/), Freek.dev (https://freek.dev/tags/eloquent)