【问题标题】:Adding Relations to Laravel Factory Model向 Laravel 工厂模型添加关系
【发布时间】:2015-12-09 00:58:37
【问题描述】:

我正在尝试添加与工厂模型的关系以执行一些数据库播种,如下所示 - 请注意,我正在尝试为每个用户添加 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 或发布给每个用户,那么我必须 decalare 10 或行,除非我使用某种 for 循环。

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());
   });
}

* 已更新 *

有没有办法将模型工厂嵌套到第三层深度?

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());
          }));
   });
}

【问题讨论】:

  • 模型有一个 saveMany() 方法,它接受 Collection 对象。试试$u->posts()->saveMany(factory(App\Post::class, 2)->make());。但是,请记住,这仍会在后台生成 2 个保存查询,它不会持续存在一个查询。
  • @Yasen:saveMany() 方法有效。有没有办法将模型工厂嵌套到更深的第 3 层?请参阅更新后的帖子了解我的意思。
  • 有没有找到2层以上嵌套的解决方案?

标签: php laravel-5 relationship factory


【解决方案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 个帖子,每个帖子有一个评论。

【讨论】:

    【解决方案2】:

    试试这个。它对我有用:

    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());
                });
    

    【讨论】:

    • 您将如何传递数据?像需要匹配的id?谢谢
    • 它是一家工厂,注意循环。循环中的所有内容都将链接到模型。
    【解决方案3】:

    对于第 3 级嵌套关系,如果您想使用正确的对应外键创建数据,您可以遍历创建帖子的所有结果,如下所示:

    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());
            });
    });
    

    【讨论】:

    • 为我解决了,我已经用谷歌搜索了半个小时试图找到令人信服的东西。
    【解决方案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( 工厂(App\Post::class, 3)->make()->toArray() );

    这意味着:

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

    【讨论】:

      【解决方案5】:
      $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)]
      ];
      });
      

      【讨论】:

        猜你喜欢
        • 2020-03-09
        • 2018-06-13
        • 2014-08-17
        • 2017-03-21
        • 2019-05-28
        • 2018-01-10
        • 1970-01-01
        • 2021-11-06
        • 2021-06-29
        相关资源
        最近更新 更多