在 laravel 中播种与模型工厂的多对多关系 - 列不能为空错误
Seeding many-to-many relationship with model factory in laravel - column cannot be null error
鉴于我有以下 tables:
- 用户
- 问题
- 标签
- question_tag
my pivot table with two fields: question_id & tag_id
这些是我的模型关系:
用户
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);
}
我已经为每个模型正确设置了数据库模型工厂。
使用我的播种机,这是我想要实现的目标:
- 种子 10 个虚拟用户
- 为每个虚拟用户设置 10 个虚拟问题
- 对于每个虚拟问题,将其与最多 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());
});
鉴于我有以下 tables:
- 用户
- 问题
- 标签
- question_tag
my pivot table with two fields: question_id & tag_id
这些是我的模型关系:
用户
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);
}
我已经为每个模型正确设置了数据库模型工厂。
使用我的播种机,这是我想要实现的目标:
- 种子 10 个虚拟用户
- 为每个虚拟用户设置 10 个虚拟问题
- 对于每个虚拟问题,将其与最多 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());
});