From 4b35f748ab30a847b6cf63db3d68e15716e34e20 Mon Sep 17 00:00:00 2001 From: mpyw Date: Mon, 28 Aug 2023 10:58:42 +0900 Subject: [PATCH] Make the `updateOrCreate` methods in relations use `firstOrCreate` behind the scenes Related to #48160, #48192 --- .../Database/Eloquent/Relations/BelongsToMany.php | 14 +++++--------- .../Database/Eloquent/Relations/HasManyThrough.php | 10 +++++----- .../Database/Eloquent/Relations/HasOneOrMany.php | 8 ++++---- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php b/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php index b2e494478211..ecfb4fb0d5e1 100755 --- a/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php +++ b/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php @@ -672,17 +672,13 @@ public function createOrFirst(array $attributes = [], array $values = [], array */ public function updateOrCreate(array $attributes, array $values = [], array $joining = [], $touch = true) { - if (is_null($instance = (clone $this)->where($attributes)->first())) { - if (is_null($instance = $this->related->where($attributes)->first())) { - return $this->create(array_merge($attributes, $values), $joining, $touch); - } else { - $this->attach($instance, $joining, $touch); - } - } + $instance = $this->firstOrCreate($attributes, $values, $joining, $touch); - $instance->fill($values); + if (! $instance->wasRecentlyCreated) { + $instance->fill($values); - $instance->save(['touch' => false]); + $instance->save(['touch' => false]); + } return $instance; } diff --git a/src/Illuminate/Database/Eloquent/Relations/HasManyThrough.php b/src/Illuminate/Database/Eloquent/Relations/HasManyThrough.php index ac5037185793..c0307e824af3 100644 --- a/src/Illuminate/Database/Eloquent/Relations/HasManyThrough.php +++ b/src/Illuminate/Database/Eloquent/Relations/HasManyThrough.php @@ -271,11 +271,11 @@ public function firstOrNew(array $attributes) */ public function updateOrCreate(array $attributes, array $values = []) { - $instance = $this->firstOrNew($attributes); - - $instance->fill($values)->save(); - - return $instance; + return tap($this->firstOrCreate($attributes, $values), function ($instance) use ($values) { + if (! $instance->wasRecentlyCreated) { + $instance->fill($values)->save(); + } + }); } /** diff --git a/src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php b/src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php index c748dd7c644d..9847a800bcb8 100755 --- a/src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php +++ b/src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php @@ -267,10 +267,10 @@ public function createOrFirst(array $attributes = [], array $values = []) */ public function updateOrCreate(array $attributes, array $values = []) { - return tap($this->firstOrNew($attributes), function ($instance) use ($values) { - $instance->fill($values); - - $instance->save(); + return tap($this->firstOrCreate($attributes, $values), function ($instance) use ($values) { + if (! $instance->wasRecentlyCreated) { + $instance->fill($values)->save(); + } }); }