If you have a potentially existing record and need to update it if it exists or create it if it doesn't. Here's how!
Let's take logging a user visit as an example. We want to uniquely log a user's last visit using their IP address. Here's what our table structure might look like:
Schema::create('visits', function (Blueprint $table) {
$table->id();
$table->string('ip_address');
$table->timestamp('last_visit');
$table->timestamps();
});
In plain English, we want to insert an initial record if the IP address hasn't already had a logged visit, but we want to update the same record if a user with the same IP address visits again.
Basically, we want to update or create.
Here's how:
Visit::updateOrCreate(
['ip_address' => request()->ip()],
['last_visit' => now()]
);
Notice we're passing two arguments here to updateOrCreate
.
So, the first time updateOCreate
runs, it'll look for a record in the visits
table with the IP address (e.g. 127.0.0.1). It'll insert (127.0.0.1, now())
if not found.
The second time it runs, it'll find a record with the IP address 127.0.0.1. But, instead of inserting a new record, it'll update the existing record with the latest value of now()
.
You can pass as many lookup values as you need to updateOrCreate
. Here's an example from the Laravel documentation:
Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99, 'discounted' => 1]
);
updateOrCreate
helps avoid manually looking up a record, checking if it exists, and then choosing between inserting or updating.
Everything is handled behind the scenes for us in the most efficient way possible.