Eloquent First Or: Find or Create Patterns
Eloquent First Or: Find or Create Patterns
Eloquent First Or: Find or Create Patterns
Tip: firstOrCreate()
$user = User::firstOrCreate(
['email' => 'john@example.com'],
['name' => 'John']
);
Finds by email, creates with name if not found.
Gotcha: firstOrNew() Doesn't Save
$user = User::firstOrNew(['email' => 'john@example.com']);
$user->name = 'John';
$user->save(); // Must call save() manually
Tip: firstOrFail() vs first()
User::where('email', 'john@example.com')->firstOrFail();
// Throws ModelNotFoundException if not found
Gotcha: Race Conditions with firstOrCreate()
Two simultaneous requests might both try to create. Use database unique constraints as a safety net.
Tip: firstOr() for Custom Fallback
$post = Post::where('slug', $slug)->firstOr(function () {
return new Post(['title' => 'Default']);
});
Gotcha: firstOrCreate() Fires Events
creating and created events fire when a new record is created. firstOrNew() doesn't fire events until save().
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 *Or* family of methods is elegant but treacherous for concurrent access. firstOrCreate() runs a SELECT followed by an INSERT, and between those two calls another process can insert the same row, causing a duplicate key exception. I always pair these methods with a database-level unique constraint as a safety net. For high-concurrency operations, I prefer explicit transaction handling with lock checks.
Source: Laravel Docs (https://laravel.com/docs/eloquent), Laravel News (https://laravel-news.com/), Freek.dev (https://freek.dev/tags/eloquent)