Skip to content

Commit d58c89f

Browse files
[9.x] Allow factories to recycle models with for method (#44265)
* Recycle models when using `for` * formatting * Add test for expected recycle behaviour * Update BelongsToRelationship.php Co-authored-by: Taylor Otwell <[email protected]>
1 parent 196680f commit d58c89f

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

src/Illuminate/Database/Eloquent/Factories/BelongsToRelationship.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ protected function resolver($key)
6969
{
7070
return function () use ($key) {
7171
if (! $this->resolved) {
72-
$instance = $this->factory instanceof Factory ? $this->factory->create() : $this->factory;
72+
$instance = $this->factory instanceof Factory
73+
? ($this->factory->recycle->get($this->factory->modelName()) ?? $this->factory->create())
74+
: $this->factory;
7375

7476
return $this->resolved = $key ? $instance->{$key} : $instance->getKey();
7577
}

src/Illuminate/Database/Eloquent/Factories/Factory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ abstract class Factory
6868
*
6969
* @var \Illuminate\Support\Collection
7070
*/
71-
protected $recycle;
71+
public $recycle;
7272

7373
/**
7474
* The "after making" callbacks that will be applied to the model.

tests/Database/DatabaseEloquentFactoryTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,37 @@ public function test_model_instances_can_be_used_in_place_of_nested_factories()
670670
$this->assertEquals($user->id, $post->comments[1]->user_id);
671671
}
672672

673+
public function test_for_method_recycles_models()
674+
{
675+
Factory::guessFactoryNamesUsing(function ($model) {
676+
return $model.'Factory';
677+
});
678+
679+
$user = FactoryTestUserFactory::new()->create();
680+
$post = FactoryTestPostFactory::new()
681+
->recycle($user)
682+
->for(FactoryTestUserFactory::new())
683+
->create();
684+
685+
$this->assertSame(1, FactoryTestUser::count());
686+
}
687+
688+
public function test_has_method_does_not_reassign_the_parent()
689+
{
690+
Factory::guessFactoryNamesUsing(function ($model) {
691+
return $model.'Factory';
692+
});
693+
694+
$post = FactoryTestPostFactory::new()->create();
695+
$user = FactoryTestUserFactory::new()
696+
->recycle($post)
697+
// The recycled post already belongs to a user, so it shouldn't be recycled here.
698+
->has(FactoryTestPostFactory::new(), 'posts')
699+
->create();
700+
701+
$this->assertSame(2, FactoryTestPost::count());
702+
}
703+
673704
/**
674705
* Get a database connection instance.
675706
*

0 commit comments

Comments
 (0)