Another “hidden gem” of Laravel which is surprisingly rarely used or even known, though it’s mentioned in the official Eloquent documentation. Imagine that you have a record, and you need to check if that record already exists in the database – to prevent duplicate, you wouldn’t save it second time. There’s an elegant way to perform it in Eloquent.
Let’s take an example – a user with email povilas@laraveldaily.com (real email, feel free to get in touch!).
Typical code would be:
$user = User::where('email', 'povilas@laraveldaily.com')->first(); if (!$user) { $user = User::create([ 'email' => 'povilas@laraveldaily.com', 'first_name' => 'Povilas', 'last_name' => 'Korop', ]); }
Now, what if I told you…
$user = User::firstOrCreate(['email' => 'povilas@laraveldaily.com'], ['first_name' => 'Povilas', 'last_name' => 'Korop']);
Yup, it’s that easy. This sentence performs the same thing – checks the user by email, and if it doesn’t exist – creates the record, filling the extra fields with the array in the second parameter.
There’s also a method called firstOrNew(). It works almost identically to firstOrCreate(), except that it doesn’t actually create a record in DB – it just returns a new Eloquent model object which then you can modify before saving:
$user = User::firstOrNew(['email' => 'povilas@laraveldaily.com'], ['first_name' => 'Povilas', 'last_name' => 'Korop']); // ... Some more manipulation on $user $user->save();
But that’s not all! You can do pretty much the same thing for updating the record.
Instead of:
$user = User::where('email', 'povilas@laraveldaily.com')->first(); if ($user) { $user->update([ 'first_name' => 'Povilas', 'last_name' => 'Korop', ]); } else { $user = User::create([ 'email' => 'povilas@laraveldaily.com', 'first_name' => 'Povilas', 'last_name' => 'Korop', ]); }
Do this:
$user = User::updateOrCreate(['email' => 'povilas@laraveldaily.com'], ['first_name' => 'Povilas', 'last_name' => 'Korop']);
Same logic of parameters here – Laravel will check for email field, and if it finds the record, it will get updated with first_name and last_name, otherwise new entry will be created with all those three fields.
Some more info and a different example – in the official Eloquent documentation.
Your post is incomplete. The title says OrCreate and OrNew but you’ve covered orCreate only. Where is OrNew part?
Hi Richard, yes you’re right – orNew is in the official docs link, but will add it to the article, too. Thanks for noticing, somehow I missed that part.
It’s a awesome solution!!! Exactly what I need!
With updateOrCreate my code will be much better)
Cheers!
I tried the updateOrcreate method.
The updateOrcreate method I use.
I have multiple select box edit form. For example: Initially I save the education data of High School graduates, Bachelor’s Degree and Master’s Degree . Then I want to turn into a graduate of Senior High School and Bachelor’s Degree . What is the example code to remove a graduate of Master’s Degree in multiple select boxes?
sometimes It through an error.
Unique violation: 7 ERROR: duplicate key value violates unique constraint “users_email_unique”
And also skip the next primary key form the DB.
$user = $this->user->updateOrCreate([‘facebook_id’ => $request->input(‘facebook_id’)],
[
‘name’ => $request->input(‘name’),
‘last_name’ => $request->input(‘last_name’),
’email’ => $request->input(’email’),
‘facebook_id’ => $request->input(‘facebook_id’),
‘dob’ => $request->input(‘dob’),
‘loggedin_at’ => now()
]
);