最近,我一直试图通过Model Factories和Faker使用Laravel播种来播种我的数据库。
对于简单的模式,让它工作是一件轻而易举的事情:)。但是,在处理涉及外键和表关系的复杂数据库模式时遇到了一些问题:
...与链接中描述的内容类似: Laravel 5.1 foreign keys in model factory
在本主题中,official documentation建议运行如下数据库种子:
public function run()
{
factory(App\User::class, 50)->create()->each(function ($u) {
$u->posts()->save(factory(App\Post::class)->make());
});
}
...但是这个解决方案存在一个问题:当处理许多数据库表并运行多个种子(它们之间有很多关系)时,创建许多不必要的模型是很常见的方法。例如,如果我们在上述示例之前运行了PostsTableSeeder.php,那么所有这些帖子都不会链接到用户,并且永远不会用于测试和开发......
因此,为了找到处理这种情况的方法,我找到了一个适用于我的功能性解决方案,并避免了那些不必要的创造“孤儿”的问题。模型...
我想和大家分享,所以答案中只是解释了:)。
答案 0 :(得分:22)
所以这是我的解决方案:
该示例处理:
用户&帖子(用于说明一对多关系)
// ONE TO ONE relationship (with Users already created)
$factory->define(App\Profile::class, function (Faker\Generator $faker) {
return [
'user_id' => $faker->unique()->numberBetween(1, App\User::count()),
// Rest of attributes...
];
});
// ONE TO MANY relationship (with Users already created)
$factory->define(App\Posts::class, function (Faker\Generator $faker) {
$users = App\User::pluck('id')->toArray();
return [
'user_id' => $faker->randomElement($users),
// Rest of attributes...
];
});
答案 1 :(得分:0)
这是一种解决方案,可以使关系比分配随机用户更好,特别是如果您需要向此模型发送额外信息。
$factory->define(App\Post::class, function (Faker\Generator $faker) {
$user = factory('App\Models\User')->create(['email' => 'email@test.com,]);
// do your relationships here (...)
return [
'user_id' => $user->id,
'title' => $faker->sentence,
'body' => $faker->paragraph,
];
}
我看到另一个使用匿名函数的例子
$factory->define(App\Post::class, function (Faker\Generator $faker) {
return [
'user_id' => function () {
return factory(App\User::class)->create()->id;
},
'title' => $faker->sentence,
'body' => $faker->paragraph,
];
}
来源:https://laracasts.com/series/laravel-from-scratch-2017/episodes/22