Passing array values to laravel factory

时间:2017-08-04 12:45:56

标签: php laravel laravel-5.4 factory faker

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.

In seeder, it calls the factory.

factory(App\Models\Types::class, 10)->create();

In Modelfactory, the function is as below

$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.

2 个答案:

答案 0 :(得分:2)

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,
    ];
});

答案 1 :(得分:1)

我个人认为工厂只是填补模型fillable attributes的一种方式。我关注播种者的关系。

假设您有两个模型TypeMaterial。您创建了两个名为TypeFactoryMaterialFactory的工厂。例如TypeFactory如下:

$factory->define(App\Models\Types::class, function (Faker\Generator $faker) {
    return [
        'display_status' => 1,
        'name' => $faker->unique()->word,
        'status' => 1
    ];
});

然后在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();
});

请注意create()make()之间的区别。 create()持久化模型,make()仅返回它的实例。

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

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