Check if row was created with Laravel updateOrCreate

12 Apr 2021 in TIL

In a recent project I needed to know if updateOrCreate created a new row or if it updated an existing row so that I could trigger some processing that only needed to be done when a new row is created.

After some digging, I discovered the wasRecentlyCreated public property on all Eloquent models:

php
$r = Tag::updateOrCreate(
['action_id' => 1, 'name' => 'my-demo-tag'],
['sha' => 'fb5dcb08af86c6b58bda3c172a6b3b1d0bfb4542'],
);
dump($r->wasRecentlyCreated);

This field is true if a row was created, and false if a row was updated.

I had to go source diving to find the property which didn’t feel right to me as Laravel generally has excellent documentation. After more searching I realised that instead of checking wasRecentlyCreated the “proper” way to handle this use case was to dispatch events whenever the model is created and updated:

php
use App\Events\TagCreated;
use App\Events\TagUpdated;
class Tag extends Model
{
protected $dispatchesEvents = [
'created' => TagCreated::class,
'updated' => TagUpdated::class,
];
}

This allows you to register listeners for those events and no matter where in your application a new row is created, the follow-up processing will always be run.