在Laravel工厂模型中添加关系

时间:2015-09-12 16:00:57

标签: relationship factory laravel-5.1

我尝试添加工厂模型的关系来进行数据库播种,如下所示 - 请注意我尝试向每个用户添加2个帖子

public function run()
{
   factory(App\User::class, 50)->create()->each(function($u) {
         $u->posts()->save(factory(App\Post::class, 2)->make());
   });
}

但它抛出以下错误

Argument 1 passed to Illuminate\Database\Eloquent\Relations\HasOneOrMany::s  
ave() must be an instance of Illuminate\Database\Eloquent\Model, instance 
of Illuminate\Database\Eloquent\Collection given

我认为这与保存集合有关。如果通过分别调用帖子的每个工厂模型重新编写代码,它似乎工作。显然这不是很优雅,因为如果我想坚持10或发布给每个用户,那么除非我使用某种for循环,否则我不得不去除10或行。

public function run()
{
   factory(App\User::class, 50)->create()->each(function($u) {
     $u->posts()->save(factory(App\Post::class)->make());
     $u->posts()->save(factory(App\Post::class)->make());
   });
}

*更新*

有没有办法将模型工厂嵌套到第3级?

public function run()
{
   factory(App\User::class, 50)
       ->create()
       ->each(function($u) {
           $u->posts()->saveMany(factory(App\Post::class, 2)
                    ->make()
                    ->each(function($p){
                          $p->comments()->save(factory(App\Comment::class)->make());
          }));
   });
}

5 个答案:

答案 0 :(得分:7)

试试这个。它对我有用:

factory(\App\Models\Auth\User::class, 300)->create()->each(function ($s) {
                    $s->spots()->saveMany(factory(\App\Models\Spots\Parking::class, 2)->create()->each(function ($u) {
                            $u->pricing()->save(factory(\App\Models\Payment\Pricing::class)->make());
                    }));
                    $s->info()->save(factory(\App\Models\User\Data::class)->make());
            });

答案 1 :(得分:4)

要回答最初的问题/错误消息:

问题确实与保存数据有关。您的代码:

$u->posts()->save(factory(App\Post::class, 2)->make());

...应更改为

$u->posts()->saveMany(factory(App\Post::class, 2)->make());

laravel docs

您可以使用createMany方法创建多个相关模型:

$ user-> posts()-> createMany( factory(App \ Post :: class,3)-> make()-> toArray() );

这意味着:

  • 仅在工厂中创建一个模型时,应使用save()或create()
  • 在工厂中创建多个模型时,应使用saveMany()或createMany()

答案 2 :(得分:1)

对于第三级嵌套关系,如果要使用正确的相应外键创建数据,可以循环创建帖子的所有结果,如下所示:

factory(App\User::class, 50)->create()->each(function($u) {
    $u->posts()
        ->saveMany( factory(App\Post::class, 2)->make() )
        ->each(function($p){
            $p->comments()->save(factory(App\Comment::class)->make());
        });
});

答案 3 :(得分:1)

从Laravel 5.6开始,有一个回调函数afterCreating & afterMaking允许您在创建/制作之后直接添加关系:

$factory->afterCreating(App\User::class, function ($user, $faker) {
    $user->saveMany(factory(App\Post::class, 10)->make());
});

$factory->afterMaking(App\Post::class, function ($post, $faker) {
    $post->save(factory(App\Comment::class)->make());
});

现在

factory(App\User::class, 50)->create()

将为您提供50个用户,每个用户有10个帖子,每个帖子都有一个评论。

答案 4 :(得分:0)

$factory->define(User::class, function (Faker $faker) {
return [
    'name' => $faker->name,
    'email' => $faker->unique()->safeEmail,
    'email_verified_at' => now(),
    'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // 
password
    'remember_token' => Str::random(10),
];
});

$factory->define(Post::class, function ($faker) use ($factory) {
return [
    'title' => $faker->sentence(3),
    'content' => $faker->paragraph(5),
    'user_id' => User::pluck('id')[$faker->numberBetween(1,User::count()-1)]
];
});