【问题标题】:Laravel eloquent multiple belongsTo seedingLaravel 雄辩的多属于播种
【发布时间】:2020-01-21 15:21:10
【问题描述】:

我有三个模型,UserCategoryArticle

Article 属于UserCategory,其中外键user_idcategory_idnot null

我试图通过工厂相应地用假数据为数据库播种,这是播种代码...

// 2 categories and 12 articles, 6 per category
// TODO: A user should have 6 articles with mixed categories 
// 3 from each category
// So we will have 2 users
factory(Category::class, 2)->create()->each(function($category) {
    factory(User::class)->create()->each(function($user) use ($category) {
        // How to assign an Article to $category or $user while creating?
        $user->articles()->createMany(
                    factory(Article::class, 3)->make()->toArray()
                ); // category_id can't be null
        // OR
        $category->articles()->createMany(
                    factory(Article::class, 3)->make()->toArray()
                ); // user_id can't be null
    });
});

我会得到两个错误之一,要么

列 user_id 没有默认值

或者

列 category_id 没有默认值

由于Article 表迁移,这是合乎逻辑的

$table->increments('id');
$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->unsignedInteger('category_id');
$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');

如何将category_iduser_id 传递给工厂调用?
有没有更好的方法来实现这一点?

提前致谢

【问题讨论】:

  • 像这样添加它们? factory(Article::class, 3)->make(['category_id' => $category->id])->toArray() 可以吗?
  • @kerbholz 是的,谢谢,把它作为答案,我会投票并接受

标签: php mysql laravel laravel-seeding


【解决方案1】:

您可以通过将具有所需属性的数组传递给make() 方法来覆盖工厂的属性:

改变

$user->articles()->createMany(
  factory(Article::class, 3)->make()->toArray()
);

$user->articles()->createMany(
  factory(Article::class, 3)->make([
    'category_id' => $category->id
  ])->toArray()
);

覆盖category_id 属性。

https://laravel.com/docs/6.x/database-testing#using-factories

【讨论】:

    【解决方案2】:

    这可能对你有帮助

    首先

    当您从工厂制作新文章时让用户创建

    $factory->define(App\Article::class, function ($faker) use ($factory)  {
        return [
            'user_id' => $factory->create(App\User::class)->id,
            'title' => $faker->sentence,
            'body' => $faker->paragraph
        ];
    });
    

    第二

    来自您的播种机 在这个例子中,我将制作 3 个类别 * 6 篇文章

    factory('App\Category', 3)->create()->each(function($u) {
        $u->posts()->save(factory('App\Article', 6)->create());
    });
    

    【讨论】:

    • $factory->create(App\User::class)->id 会为每篇文章创建一个新用户,不满足A user should have 6 articles 的要求,这样一个用户将只有一篇文章
    • 没有第一部分只是为了在工厂创建用户 foreach 文章,但在你的播种机中你将创建 3 个类别,每个类别有 6 篇文章
    【解决方案3】:

    分别播种类别。

    然后播种用户并在其中播种文章。 在文章工厂文件ArticleFactory

    $factory->define(App\Article::class, function (Faker $faker) {
    
        return [
            'category_id' => App\Category::inRandomOrder()->value('id'),
            ....
            'created_at' => time(),
            'updated_at' => time(),
        ];
    });
    

    【讨论】:

    • inRandomOrder 达不到每个类别 6 篇文章的要求
    • @CaddyDZ 然后将其更改为withCount('articles')->orderBy('articles_count', 'asc')
    猜你喜欢
    • 2016-07-30
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多