将数组值传递给 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 16:27:16  来源:igfitidea点击:

Passing array values to laravel factory

phplaravellaravel-5.4factoryfaker

提问by Krishna Raj K

I'm trying to create a fake data seeder using fzaninotto/fakerand factoryin 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 $materialsis created with the model call to Materialis 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 Modelfactoryis loaded at the beginning by default.

该数组$materialsMaterial在每个循环中通过模型调用创建的,我想避免这种情况。播种更多数据(比如 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 Typeand Material. You create two factories named TypeFactoryand MaterialFactory. For instance TypeFactorywould be as follows:

假设您有两个模型TypeMaterial. 您创建了两个名为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 typestable, 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 pluckmethod:

这可能与您的问题无关,但App\Models\Material::pluck('id')->all()不正确。您应该首先检索模型的所有实例,然后调用该pluck方法:

$materialsIds = App\Models\Material::all()->pluck('id');