diff --git a/src/Illuminate/Database/Eloquent/Factories/BelongsToManyRelationship.php b/src/Illuminate/Database/Eloquent/Factories/BelongsToManyRelationship.php index 6395b28e02a2..e0c42c4c642b 100644 --- a/src/Illuminate/Database/Eloquent/Factories/BelongsToManyRelationship.php +++ b/src/Illuminate/Database/Eloquent/Factories/BelongsToManyRelationship.php @@ -10,7 +10,7 @@ class BelongsToManyRelationship /** * The related factory instance. * - * @var \Illuminate\Database\Eloquent\Factories\Factory + * @var \Illuminate\Database\Eloquent\Factories\Factory|\Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model */ protected $factory; @@ -31,12 +31,12 @@ class BelongsToManyRelationship /** * Create a new attached relationship definition. * - * @param \Illuminate\Database\Eloquent\Factories\Factory $factory + * @param \Illuminate\Database\Eloquent\Factories\Factory|\Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model $factory * @param callable|array $pivot * @param string $relationship * @return void */ - public function __construct(Factory $factory, $pivot, $relationship) + public function __construct($factory, $pivot, $relationship) { $this->factory = $factory; $this->pivot = $pivot; @@ -51,7 +51,7 @@ public function __construct(Factory $factory, $pivot, $relationship) */ public function createFor(Model $model) { - Collection::wrap($this->factory->create([], $model))->each(function ($attachable) use ($model) { + Collection::wrap($this->factory instanceof Factory ? $this->factory->create([], $model) : $this->factory)->each(function ($attachable) use ($model) { $model->{$this->relationship}()->attach( $attachable, is_callable($this->pivot) ? call_user_func($this->pivot, $model) : $this->pivot diff --git a/src/Illuminate/Database/Eloquent/Factories/BelongsToRelationship.php b/src/Illuminate/Database/Eloquent/Factories/BelongsToRelationship.php index 1a4ceb3c0d0b..55747fdc6488 100644 --- a/src/Illuminate/Database/Eloquent/Factories/BelongsToRelationship.php +++ b/src/Illuminate/Database/Eloquent/Factories/BelongsToRelationship.php @@ -10,7 +10,7 @@ class BelongsToRelationship /** * The related factory instance. * - * @var \Illuminate\Database\Eloquent\Factories\Factory + * @var \Illuminate\Database\Eloquent\Factories\Factory|\Illuminate\Database\Eloquent\Model */ protected $factory; @@ -31,11 +31,11 @@ class BelongsToRelationship /** * Create a new "belongs to" relationship definition. * - * @param \Illuminate\Database\Eloquent\Factories\Factory $factory + * @param \Illuminate\Database\Eloquent\Factories\Factory|\Illuminate\Database\Eloquent\Model $factory * @param string $relationship * @return void */ - public function __construct(Factory $factory, $relationship) + public function __construct($factory, $relationship) { $this->factory = $factory; $this->relationship = $relationship; @@ -52,7 +52,7 @@ public function attributesFor(Model $model) $relationship = $model->{$this->relationship}(); return $relationship instanceof MorphTo ? [ - $relationship->getMorphType() => $this->factory->newModel()->getMorphClass(), + $relationship->getMorphType() => $this->factory instanceof Factory ? $this->factory->newModel()->getMorphClass() : $this->factory->getMorphClass(), $relationship->getForeignKeyName() => $this->resolver($relationship->getOwnerKeyName()), ] : [ $relationship->getForeignKeyName() => $this->resolver($relationship->getOwnerKeyName()), @@ -69,7 +69,7 @@ protected function resolver($key) { return function () use ($key) { if (! $this->resolved) { - $instance = $this->factory->create(); + $instance = $this->factory instanceof Factory ? $this->factory->create() : $this->factory; return $this->resolved = $key ? $instance->{$key} : $instance->getKey(); } diff --git a/src/Illuminate/Database/Eloquent/Factories/Factory.php b/src/Illuminate/Database/Eloquent/Factories/Factory.php index 925614371297..e383bf6fb135 100644 --- a/src/Illuminate/Database/Eloquent/Factories/Factory.php +++ b/src/Illuminate/Database/Eloquent/Factories/Factory.php @@ -481,12 +481,12 @@ protected function guessRelationship(string $related) /** * Define an attached relationship for the model. * - * @param \Illuminate\Database\Eloquent\Factories\Factory $factory + * @param \Illuminate\Database\Eloquent\Factories\Factory|\Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model $factory * @param callable|array $pivot * @param string|null $relationship * @return static */ - public function hasAttached(self $factory, $pivot = [], $relationship = null) + public function hasAttached($factory, $pivot = [], $relationship = null) { return $this->newInstance([ 'has' => $this->has->concat([new BelongsToManyRelationship( @@ -500,11 +500,11 @@ public function hasAttached(self $factory, $pivot = [], $relationship = null) /** * Define a parent relationship for the model. * - * @param \Illuminate\Database\Eloquent\Factories\Factory $factory + * @param \Illuminate\Database\Eloquent\Factories\Factory|\Illuminate\Database\Eloquent\Model $factory * @param string|null $relationship * @return static */ - public function for(self $factory, $relationship = null) + public function for($factory, $relationship = null) { return $this->newInstance(['for' => $this->for->concat([new BelongsToRelationship( $factory, diff --git a/tests/Database/DatabaseEloquentFactoryTest.php b/tests/Database/DatabaseEloquentFactoryTest.php index 3b87fca3ee58..3c575e8ce989 100644 --- a/tests/Database/DatabaseEloquentFactoryTest.php +++ b/tests/Database/DatabaseEloquentFactoryTest.php @@ -250,6 +250,21 @@ public function test_belongs_to_relationship() $this->assertCount(3, FactoryTestPost::all()); } + public function test_belongs_to_relationship_with_existing_model_instance() + { + $user = FactoryTestUserFactory::new(['name' => 'Taylor Otwell'])->create(); + $posts = FactoryTestPostFactory::times(3) + ->for($user, 'user') + ->create(); + + $this->assertCount(3, $posts->filter(function ($post) use ($user) { + return $post->user->is($user); + })); + + $this->assertCount(1, FactoryTestUser::all()); + $this->assertCount(3, FactoryTestPost::all()); + } + public function test_morph_to_relationship() { $posts = FactoryTestCommentFactory::times(3) @@ -263,6 +278,20 @@ public function test_morph_to_relationship() $this->assertCount(3, FactoryTestComment::all()); } + public function test_morph_to_relationship_with_existing_model_instance() + { + $post = FactoryTestPostFactory::new(['title' => 'Test Title'])->create(); + $posts = FactoryTestCommentFactory::times(3) + ->for($post, 'commentable') + ->create(); + + $this->assertSame('Test Title', FactoryTestPost::first()->title); + $this->assertCount(3, FactoryTestPost::first()->comments); + + $this->assertCount(1, FactoryTestPost::all()); + $this->assertCount(3, FactoryTestComment::all()); + } + public function test_belongs_to_many_relationship() { $users = FactoryTestUserFactory::times(3) @@ -290,6 +319,29 @@ public function test_belongs_to_many_relationship() unset($_SERVER['__test.role.creating-user']); } + public function test_belongs_to_many_relationship_with_existing_model_instances() + { + $roles = FactoryTestRoleFactory::times(3) + ->afterCreating(function ($role) { + $_SERVER['__test.role.creating-role'] = $role; + }) + ->create(); + FactoryTestUserFactory::times(3) + ->hasAttached($roles, ['admin' => 'Y'], 'roles') + ->create(); + + $this->assertCount(3, FactoryTestRole::all()); + + $user = FactoryTestUser::latest()->first(); + + $this->assertCount(3, $user->roles); + $this->assertSame('Y', $user->roles->first()->pivot->admin); + + $this->assertInstanceOf(Eloquent::class, $_SERVER['__test.role.creating-role']); + + unset($_SERVER['__test.role.creating-role']); + } + public function test_sequences() { $users = FactoryTestUserFactory::times(2)->sequence(