对于以下工厂定义,列order
必须是连续的。已经有一个列id
,该列会自动增加。第一行的order
应该从1
开始,其他每一行的order
应该是下一个数字(1
,2
,3
等)
$factory->define(App\AliasCommand::class, function (Faker\Generator $faker) {
return [
'user_id' => App\User::inRandomOrder()->first()->id,
'command' => $faker->word,
'content' => $faker->sentence,
'order' => (App\AliasCommand::count()) ?
App\AliasCommand::orderBy('order', 'desc')->first()->order + 1 : 1
];
});
应该将order
列设置为比前一行多1,但是,这会导致所有行都被分配了1
。
这里可能有用。
$factory->define(App\AliasCommand::class, function (Faker\Generator $faker) {
static $order = 1;
return [
'user_id' => App\User::inRandomOrder()->first()->id,
'command' => $faker->word,
'content' => $faker->sentence,
'order' => $order++
];
});
它只是在该函数内部保留一个计数器。
要获得真正的autoIncrement,请使用此方法:
$__count = App\AliasCommand::count();
$__lastid = $__count ? App\AliasCommand::orderBy('order', 'desc')->first()->id : 0 ;
$factory->define(App\AliasCommand::class,
function(Faker\Generator $faker) use($__lastid){
return [
'user_id' => App\User::inRandomOrder()->first()->id,
'command' => $faker->word,
'content' => $faker->sentence,
'order' => $faker->unique()->numberBetween($min=$__lastid+1, $max=$__lastid+25),
/* +25 (for example here) is the number of records you want to insert
per run.
You can set this value in a config file and get it from there
for both Seeder and Factory ( i.e here ).
*/
];
});
@ apokryfos的答案是一个很好的解决方案,如果您确定工厂模型生成将仅按顺序运行,并且您不关心预先存在的数据。
但是,例如,如果您要生成要插入到已存在某些记录的测试数据库中的模型,则这可能会导致错误的order
值。
使用闭包作为列值,我们可以更好地自动化顺序。
$factory->define(App\AliasCommand::class, function (Faker\Generator $faker) {
return [
'user_id' => App\User::inRandomOrder()->first()->id,
'command' => $faker->word,
'content' => $faker->sentence,
'order' => function() {
$max = App\AliasCommand::max('order'); // returns 0 if no records exist.
return $max+1;
}
];
});
在您的示例中您几乎是对的,问题是您正在运行order
值执行在定义工厂时,而不是上面的代码,该代码在模型生成。
根据相同的原理,还应该将user_id
代码括在一个闭包中,否则所有工厂生成的模型都将具有相同的用户ID。