Skip to content

Commit 4b4b1e4

Browse files
mpywfuwasegu
andauthored
[10.x] Revival of the reverted changes in 10.25.0: firstOrCreate updateOrCreate improvement through createOrFirst + additional query tests (#48637)
* Revert "[10.x] Revert from using `createOrFirst` in other `*OrCreate` methods (#48531)" This reverts commit 408a3e3. * test: 💍 Add `Builder::createOrFirst()` snapshot tests * test: 💍 Add `Builder::firstOrCreate()` snapshot tests * test: 💍 Add `Builder::updateOrCreate()` snapshot tests * test: 💍 Add test stubs for `DatabaseEloquentHasManyTest` * test: 💍 Add `HasMany::createOrFirst()` snapshot tests * test: 💍 Add `HasMany::firstOrCreate()` snapshot tests * test: 💍 Add `HasMany::updateOrCreate()` snapshot tests * test: 💍 prepare HasManyThrough test * test: 💍 Add HasManyThrough::CreateOrFirst() snapshot tests * test: 💍 Add HasManyThrough::firstOrCreate() snapshot test * test: 💍 Add HasManyThrough::updateOrCreate() snapshot test * refactor: 💡 use createOrFirst in firstOrCreate * test: 💍 fix test * style: 💄 Apply StyleCI fixes * docs: ✏️ Add missing FIXME comments * refactor: 💡 Omit verbose arguments * test: 💍 Rename `DatabaseEloquentHasManyThroughTest` with fixes * test: 💍 Add `BelongsToMany::createOrFirst/firstOrCreate` tests * test: 💍 Extract `DatabaseEloquentHasManyTest` cases with fixes * test: 💍 Extract `DatabaseEloquentBuilderTest` cases with fixes * test: 💍 refactoring * test: 💍 Add `BelongsToMany::updateOrCreate` snapshot tests --------- Co-authored-by: fuwasegu <[email protected]>
1 parent 56beb0e commit 4b4b1e4

10 files changed

+1670
-33
lines changed

src/Illuminate/Database/Eloquent/Builder.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ public function firstOrCreate(array $attributes = [], array $values = [])
567567
return $instance;
568568
}
569569

570-
return $this->create(array_merge($attributes, $values));
570+
return $this->createOrFirst($attributes, $values);
571571
}
572572

573573
/**
@@ -595,8 +595,10 @@ public function createOrFirst(array $attributes = [], array $values = [])
595595
*/
596596
public function updateOrCreate(array $attributes, array $values = [])
597597
{
598-
return tap($this->firstOrNew($attributes), function ($instance) use ($values) {
599-
$instance->fill($values)->save();
598+
return tap($this->firstOrCreate($attributes, $values), function ($instance) use ($values) {
599+
if (! $instance->wasRecentlyCreated) {
600+
$instance->fill($values)->save();
601+
}
600602
});
601603
}
602604

src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ public function firstOrCreate(array $attributes = [], array $values = [], array
622622
{
623623
if (is_null($instance = (clone $this)->where($attributes)->first())) {
624624
if (is_null($instance = $this->related->where($attributes)->first())) {
625-
$instance = $this->create(array_merge($attributes, $values), $joining, $touch);
625+
$instance = $this->createOrFirst($attributes, $values, $joining, $touch);
626626
} else {
627627
try {
628628
$this->getQuery()->withSavepointIfNeeded(fn () => $this->attach($instance, $joining, $touch));
@@ -672,19 +672,13 @@ public function createOrFirst(array $attributes = [], array $values = [], array
672672
*/
673673
public function updateOrCreate(array $attributes, array $values = [], array $joining = [], $touch = true)
674674
{
675-
if (is_null($instance = (clone $this)->where($attributes)->first())) {
676-
if (is_null($instance = $this->related->where($attributes)->first())) {
677-
return $this->create(array_merge($attributes, $values), $joining, $touch);
678-
} else {
679-
$this->attach($instance, $joining, $touch);
680-
}
681-
}
682-
683-
$instance->fill($values);
675+
return tap($this->firstOrCreate($attributes, $values, $joining, $touch), function ($instance) use ($values) {
676+
if (! $instance->wasRecentlyCreated) {
677+
$instance->fill($values);
684678

685-
$instance->save(['touch' => false]);
686-
687-
return $instance;
679+
$instance->save(['touch' => false]);
680+
}
681+
});
688682
}
689683

690684
/**

src/Illuminate/Database/Eloquent/Relations/HasManyThrough.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ public function firstOrCreate(array $attributes = [], array $values = [])
277277
return $instance;
278278
}
279279

280-
return $this->create(array_merge($attributes, $values));
280+
return $this->createOrFirst(array_merge($attributes, $values));
281281
}
282282

283283
/**
@@ -305,11 +305,11 @@ public function createOrFirst(array $attributes = [], array $values = [])
305305
*/
306306
public function updateOrCreate(array $attributes, array $values = [])
307307
{
308-
$instance = $this->firstOrNew($attributes);
309-
310-
$instance->fill($values)->save();
311-
312-
return $instance;
308+
return tap($this->firstOrCreate($attributes, $values), function ($instance) use ($values) {
309+
if (! $instance->wasRecentlyCreated) {
310+
$instance->fill($values)->save();
311+
}
312+
});
313313
}
314314

315315
/**

src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ public function firstOrNew(array $attributes = [], array $values = [])
236236
public function firstOrCreate(array $attributes = [], array $values = [])
237237
{
238238
if (is_null($instance = $this->where($attributes)->first())) {
239-
$instance = $this->create(array_merge($attributes, $values));
239+
$instance = $this->createOrFirst($attributes, $values);
240240
}
241241

242242
return $instance;
@@ -267,10 +267,10 @@ public function createOrFirst(array $attributes = [], array $values = [])
267267
*/
268268
public function updateOrCreate(array $attributes, array $values = [])
269269
{
270-
return tap($this->firstOrNew($attributes), function ($instance) use ($values) {
271-
$instance->fill($values);
272-
273-
$instance->save();
270+
return tap($this->firstOrCreate($attributes, $values), function ($instance) use ($values) {
271+
if (! $instance->wasRecentlyCreated) {
272+
$instance->fill($values)->save();
273+
}
274274
});
275275
}
276276

0 commit comments

Comments
 (0)