在 laravel 中播种与模型工厂的多对多关系 - 列不能为空错误

Seeding many-to-many relationship with model factory in laravel - column cannot be null error

鉴于我有以下 tables:

这些是我的模型关系:

用户

public function questions()
{
    return $this->hasMany(Question::class);
}

问题

public function user()
{
    return $this->belongsTo(User::class);
}

public function tags()
{
    return $this->belongsToMany(Tag::class);
}

标签

public function questions()
{
    return $this->belongsToMany(Question::class);
}

我已经为每个模型正确设置了数据库模型工厂。

使用我的播种机,这是我想要实现的目标:

  1. 种子 10 个虚拟用户
  2. 为每个虚拟用户设置 10 个虚拟问题
  3. 对于每个虚拟问题,将其与最多 5 个随机标签相关联

为了实现以上三个目标,我编写了如下数据库播种器:

// Seed dummy users
factory(App\User::class, 10)->create()->each(function($user)
{
    // With dummy questions
    $user->questions()->saveMany(factory(App\Question::class, 10)->make()->each(function($question)
    {
        // With dummy tags
        $question->tags()->sync(factory(App\Tag::class, 5)->make());
    }));
});

运行时,出现以下错误:

[Illuminate\Database\QueryException] SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'question_id' cannot be null (SQL: i nsert into question_tag (question_id, tag_id) values (, 1))

[PDOException] SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'question_id' cannot be null

如何在通过数据库模型工厂创建记录的同时为数据透视表播种 table?


这个问题是 我问的另一个问题 - 但现在我遇到了不同的错误。

我是这样解决的:

<?php

use Illuminate\Database\Seeder;

class DummyDataSeeder extends Seeder
{
    public function run()
    {
        // Seed dummy tags
        factory(App\Tag::class, 10)->create();
        $tagIds = DB::table('tags')->pluck('id')->toArray();

        // Seed dummy users
        factory(App\User::class, 10)->create()->each(function($user) use($tagIds)
        {
            // With dummy questions
            $user->questions()->saveMany(factory(App\Question::class, 3)
            ->create(['user_id' => $user->id])->each(function($question) use($tagIds)
            {
                // With dummy tags
                $question->tags()->sync(array_random($tagIds, mt_rand(1, 5)));
            }));
        });
    }
}

也许有更好的方法;但这对我有用。

当您使用 saveMany 方法时, 你应该像这样设置 Eloquent 模型实例作为参数。

$user->questions()->saveMany(factory(App\Question::class, 10)->make())->each(function($question)
{
    // With dummy tags
    $question->tags()->sync(factory(App\Tag::class, 5)->make());
});