Laravel check if updateOrCreate performed update

Sergej Fomin picture Sergej Fomin · Aug 16, 2017 · Viewed 13.6k times · Source

I have the following code in my controller:

for($i=0; $i<$number_of_tourists; $i++) {

$tourist = Tourist::updateOrCreate(['doc_number' => $request['doc_number'][$i]],
$tourist_to_update);

}

each time "updateOrCreate" works, it does 1 of 3 things:

1) updates model instanse OR

2) creates and saves a new one OR

3) leaves everything unchanged (if model with such values already exists).

I need to check if 'updateOrCreate' has done exactly 1 (updated) and then execute some code.

How can I do it?

Thank you in advance!

Answer

Adam picture Adam · Mar 18, 2018

You can figure it out like this:

$tourist = Tourist::updateOrCreate([...]);

if(!$tourist->wasRecentlyCreated && $tourist->wasChanged()){
    // updateOrCreate performed an update
}

if(!$tourist->wasRecentlyCreated && !$tourist->wasChanged()){
    // updateOrCreate performed nothing, row did not change
}

if($tourist->wasRecentlyCreated){
   // updateOrCreate performed create
}

Remarks

In Laravel 5.5 you can finally check if updates have actually taken place with the wasChanged and isDirty method.

  • isDirty() is true if model attribute has been changed and not saved.
  • wasChanged() is true if model attribute has been changed and saved.

There is also a property (not method!) wasRecentlyCreated to check if user was created or not.

$user = factory(\App\User::class)->create();

$user->wasRecentlyCreated; // true
$user->wasChanged(); // false
$user->isDirty(); // false

$user = \App\User::find($user->id);

$user->wasRecentlyCreated; // false
$user->wasChanged(); // false
$user->isDirty(); // false

$user->vorname = 'Max';

$user->wasChanged(); // false
$user->isDirty(); // true

$user->save();

$user->wasChanged(); // true
$user->isDirty(); // false

//You can also check if a specific attribute was changed:
$user->wasChanged('name');
$user->isDirty('name');