将数组值传递给 Laravel 工厂
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45507225/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing array values to laravel factory
提问by Krishna Raj K
I'm trying to create a fake data seeder using fzaninotto/faker
and factory
in Laravel 5.4. I want to send an array of data to the factory, in which i can pick a random element using faker. The array is a result of a DB query, which I don't want to do recursively in the Modelfactory. Here is what I done.
我正在尝试使用Laravel 5.4 中的fzaninotto/faker
和来创建一个假数据播种机factory
。我想向工厂发送一组数据,在工厂中我可以使用 faker 选择一个随机元素。该数组是 DB 查询的结果,我不想在 Modelfactory 中递归执行。这是我所做的。
In seeder, it calls the factory.
在播种机中,它调用工厂。
factory(App\Models\Types::class, 10)->create();
In Modelfactory, the function is as below
在Modelfactory中,函数如下
$factory->define(App\Models\Types::class, function (Faker\Generator $faker) {
$materials = App\Models\Material::pluck('id')->all();
return [
'name' => $faker->unique()->word,
'material_id' => $faker->randomElement($materials),
'status' => 1,
'display_status' => 1,
];
});
The array $materials
is created with the model call to Material
is done in each loop, which I want to avoid. It takes too much time to seed more data (say 100000). Is there any option pass the data from seeder file to factory? Moving the Model call before the factory definition will now solve my issue because the Material is seeded in some other seeder file, which results empty array because the Modelfactory
is loaded at the beginning by default.
该数组$materials
是Material
在每个循环中通过模型调用创建的,我想避免这种情况。播种更多数据(比如 100000)需要太多时间。是否有任何选项将数据从播种机文件传递到工厂?在工厂定义之前移动 Model 调用现在可以解决我的问题,因为材质是在其他一些播种器文件中播种的,这会导致空数组,因为Modelfactory
默认情况下在开始时加载。
回答by sbrn
Define materials above private function, and 'use' it:
在私有函数之上定义材料,并“使用”它:
$materials = App\Models\Material::pluck('id')->all();
$factory->define(App\Models\Types::class, function (Faker\Generator $faker) use ($materials)
{
return [
'name' => $faker->unique()->word,
'material_id' => $faker->randomElement($materials),
'status' => 1,
'display_status' => 1,
];
});
回答by louisfischer
I personally consider factories as just a way to fill fillable attributesof a model. I take care of the relationships in the seeders.
我个人认为工厂只是一种填充模型可填充属性的方法。我照顾播种机中的关系。
Let's say you have two models Type
and Material
. You create two factories named TypeFactory
and MaterialFactory
. For instance TypeFactory
would be as follows:
假设您有两个模型Type
和Material
. 您创建了两个名为TypeFactory
和 的工厂MaterialFactory
。例如TypeFactory
将如下:
$factory->define(App\Models\Types::class, function (Faker\Generator $faker) {
return [
'display_status' => 1,
'name' => $faker->unique()->word,
'status' => 1
];
});
Then in the seeder of the types
table, you could do:
然后在types
表的播种机中,您可以执行以下操作:
$materials = factory(App\Models\Material::class, 10)->create();
$types = factory(App\Models\Type::class, 100)->make();
$types->each(function($type) use ($materials) {
$material = $materials->random();
$type->material()->associate($material);
$type->save();
});
Note the difference between create()
and make()
. create()
persists the model and make()
only returns an instance of it.
注意之间的差异create()
和make()
。create()
持久化模型并且make()
只返回它的一个实例。
This is probably not related to your problem but App\Models\Material::pluck('id')->all()
is not correct. You should first retrieve all instances of the model and then call the pluck
method:
这可能与您的问题无关,但App\Models\Material::pluck('id')->all()
不正确。您应该首先检索模型的所有实例,然后调用该pluck
方法:
$materialsIds = App\Models\Material::all()->pluck('id');