Laravel Eloquent has quite a few "two-in-one" features: do something or do something else. And I will demonstrate a few of them now.
What if you want to get the first record by some condition and create that record if it doesn't exist?
So, this is a typical code. You do where()
and then first()
. If it doesn't return anything, then you create the record.
use App\Models\User; class HomeController extends Controller{ public function index() { $user = User::where('email', 'admin@admin.com')->first(); if (! $user) { User::create([ 'name' => 'Admin', 'email' => 'admin@admin.com', 'password' => bcrypt('password'), ]); } return $user->id; }}
Laravel allows you to do that in one sentence without the if-statement, with firstOrCreate()
.
use App\Models\User; class HomeController extends Controller{ public function index() { $user = User::firstOrCreate( ['email' => 'admin@admin.com'], ['name' => 'Admin', 'password' => bcrypt('password')] ); return $user->id; }}
There are two parameters here. So first, by which condition should you specify more fields. The second parameter is other fields for creating a record.
Similar to the first example, but here the record isn't saved to the database. You may want to do some more magic or more operations with that.
use App\Models\User; class HomeController extends Controller{ public function index() { $user = User::firstOrNew( ['email' => 'admin@admin.com'], ['name' => 'Admin', 'password' => bcrypt('password')] ); return $user->id; }}
So, the result is the user object in the variable, but it still needs to be saved into the database.
The following example is what if you want to update the record or create it if it doesn't exist.
use App\Models\User; class HomeController extends Controller{ public function index() { $user = User::updateOrCreate( ['email' => 'admin@admin.com'], ['name' => 'Admin Updated', 'password' => bcrypt('password')] ); return $user->id . ' - ' . $user->name; }}
Very similar to other examples. You update the user by that email with the values provided in the second parameter.
And the final example is upsert()
. If you have, for example, some Excel sheet with the updated data for the user and you don't want to do a foreach loop and update them automatically one by one. You want to have one sentence.
So imagine that the first two lines come with email, name, and password from the Excel sheet, and those should be the new values for the users.
use App\Models\User; class HomeController extends Controller{ public function index() { User::upsert([ ['email' => 'admin@admin.com', 'name' => 'Admin 1', 'password' => bcrypt('password')], ['email' => 'admin2@admin.com', 'name' => 'Admin 2', 'password' => bcrypt('password')], ], ['email'], ['name', 'password']); }}
Now, how do we identify the users? We identify them by email and update name and password fields. For every line, it searches for the email and updates the record with values in the last parameter, name, and password.
So, these are helpful Eloquent two-in-one methods to help you avoid two or more sentences. Instead, doing something more compactly.