Laravel Eloquent: create(), firstOrCreate(), firstOrNew() und updateOrCreate() richtig einsetzen
Wie sich die Create-Familie in Eloquent unterscheidet, wann Mass Assignment wichtig ist und welche Methode du für Inserts, Idempotenz und Upserts einsetzen solltest.
Laravel bietet mit create(), firstOrCreate(),
firstOrNew() und updateOrCreate() mehrere Wege,
Datensätze elegant anzulegen. Welche Methode sinnvoll ist, hängt davon ab, ob du nur speichern, Duplikate vermeiden,
vor dem Speichern noch eingreifen oder bestehende Datensätze direkt aktualisieren willst.
Einleitung
Eloquent gehört zu den angenehmsten Teilen von Laravel, weil viele typische Datenbankaufgaben mit sehr wenig Code lösbar sind. Besonders praktisch ist dabei die sogenannte Create-Familie: mehrere Methoden, die ähnliche Ziele verfolgen, sich im Detail aber deutlich unterscheiden.
Genau diese Unterschiede sind im Alltag wichtig. Wer die falsche Methode einsetzt, erzeugt schnell doppelte Daten, verliert Kontrolle über den Speicherzeitpunkt oder schreibt unnötig komplizierten Code rund um einfache Inserts und Updates.
Problem
Viele Laravel-Projekte starten mit einem simplen Model::create(). Das ist für neue Datensätze ideal, reicht aber nicht immer aus.
Sobald ein Datensatz vielleicht schon existiert, vor dem Speichern noch verändert werden soll oder ein Update bei Treffer gewünscht ist,
wird die Entscheidung relevanter.
Typische Fragen in der Praxis sind:
- Wie lege ich einen Datensatz nur an, wenn er noch nicht existiert?
- Wie kann ich Attribute ergänzen, bevor wirklich gespeichert wird?
- Wie ersetze ich Find-oder-Update-Logik durch kompakteren Code?
- Wie verhindere ich Fehler beim Mass Assignment?
Genau hier hilft es, die Methoden nicht nur namentlich zu kennen, sondern ihren Einsatzzweck sauber auseinanderzuhalten.
Lösungen im Vergleich
1. create()
create() ist die direkteste Variante. Du übergibst ein Attribut-Array und Eloquent speichert sofort einen neuen Datensatz.
Wichtig ist dabei, dass das Modell korrekt über $fillable oder $guarded abgesichert ist.
User::create([
'name' => 'Max Mustermann',
'email' => 'max@example.com',
'password' => bcrypt('secret'),
]);
Vorteile: kurz, lesbar und ideal für echte Neuanlagen.
Nachteile: prüft nicht, ob bereits ein passender Datensatz existiert.
2. firstOrCreate()
firstOrCreate() sucht zunächst anhand definierter Attribute. Nur wenn kein Treffer gefunden wird, legt Laravel den Datensatz an.
Das ist besonders nützlich für Seedings, Imports oder idempotente Prozesse.
User::firstOrCreate(
['email' => 'max@example.com'],
['name' => 'Max Mustermann', 'password' => bcrypt('secret')]
);
Vorteile: verhindert doppelte Einträge in vielen Standardfällen.
Nachteile: speichert sofort und ist daher ungeeignet, wenn vor dem Persistieren noch Logik nötig ist.
3. firstOrNew()
firstOrNew() arbeitet ähnlich wie firstOrCreate(), speichert aber nicht automatisch.
Du erhältst stattdessen ein Modellobjekt, das du noch anpassen, validieren oder mit zusätzlicher Logik versehen kannst.
$user = User::firstOrNew(
['email' => 'max@example.com'],
['name' => 'Max Mustermann']
);
$user->password = bcrypt('secret');
$user->save();
Vorteile: maximale Kontrolle vor dem Speichern.
Nachteile: etwas mehr Code als bei den sofort speichernden Varianten.
4. updateOrCreate()
updateOrCreate() ist die richtige Wahl, wenn ein Datensatz bei Treffer aktualisiert und sonst neu angelegt werden soll.
Für typische Upsert-Szenarien ist das oft die kompakteste und verständlichste Lösung.
User::updateOrCreate(
['email' => 'max@example.com'],
['name' => 'Max Mustermann', 'status' => 'active']
);
Vorteile: reduziert wiederkehrende Find-then-Update-Logik auf eine klare Zeile.
Nachteile: du musst trotzdem verstehen, ob fachlich wirklich ein Update statt einer Neuanlage gewollt ist.
5. Mass Assignment und Kontrolle im Alltag
Die Create-Methoden sind bequem, setzen aber eine saubere Modellkonfiguration voraus.
Wichtig:
class User extends Model
{
protected $fillable = ['name', 'email', 'password', 'status'];
}
Ohne passende Freigabe in $fillable oder eine bewusste $guarded-Strategie schlagen Mass-Assignment-basierte Methoden fehl.
Praktischer Zusatz: Bei firstOrCreate() und updateOrCreate() kannst du über wasRecentlyCreated erkennen, ob wirklich neu angelegt wurde.
Empfehlung
In der Praxis funktioniert folgende Einordnung besonders gut:
- Für klare Neuanlagen:
create(). - Für idempotente Anlage ohne Dubletten:
firstOrCreate(). - Für volle Kontrolle vor dem Speichern:
firstOrNew(). - Für Update-oder-Anlage-Szenarien:
updateOrCreate(). - Vor jeder Nutzung: Mass Assignment im Modell sauber definieren.
Best Practice:
Nutze create() nur dann, wenn ein neuer Datensatz fachlich sicher ist.
Sobald Dubletten möglich sind oder ein bestehender Treffer sinnvoll aktualisiert werden soll,
sind firstOrCreate() oder updateOrCreate() meist die robustere Wahl.
Fazit
Die Create-Familie von Eloquent spart viel Boilerplate, wenn ihre Unterschiede bewusst eingesetzt werden. Statt jeden Datensatzfluss manuell zu programmieren, kannst du in Laravel sehr präzise beschreiben, ob ein Modell sofort gespeichert, nur vorbereitet oder bei Bedarf aktualisiert werden soll.
Entscheidend ist nicht nur, dass ein Datensatz entsteht, sondern unter welchen Bedingungen.
Genau darin liegt der praktische Wert von create(), firstOrCreate(),
firstOrNew() und updateOrCreate().