【问题标题】:Passing array values to laravel factory将数组值传递给 laravel 工厂
【发布时间】:2023-03-06 12:37:01
【问题描述】:

我正在尝试在 Laravel 5.4 中使用 fzaninotto/fakerfactory 创建一个假数据播种器。我想向工厂发送一个数据数组,我可以在其中使用faker选择一个随机元素。该数组是数据库查询的结果,我不想在 Modelfactory 中递归地执行此操作。这是我所做的。

在播种机中,它调用工厂。

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

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

数组$materials 是在每个循环中通过对Material 的模型调用创建的,我想避免这种情况。播种更多数据(比如 100000)需要太多时间。是否有任何选项将数据从播种机文件传递到工厂?在工厂定义之前移动模型调用现在可以解决我的问题,因为材质是在其他播种器文件中播种的,这会导致空数组,因为默认情况下会在开头加载 Modelfactory

【问题讨论】:

    标签: php laravel laravel-5.4 factory faker


    【解决方案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');
    

    【讨论】:

    • 感谢您的信息。
    • 不,不是。因为,材料是使用 DatabaseSeeder 播种的,而类型是使用 DummySeeder 文件播种的。所以我不能将它们合并到一个文件中。
    • 您知道您可以将其他种子文件导入DatabaseSeeder.php。在run() 方法中,只需执行$this->call(DummySeeder::class);
    • DummySeeder 是可选的。我不能在DatabaseSeeder 中包含它。
    【解决方案2】:

    在私有函数之上定义材料,并“使用”它:

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

    【讨论】:

    • 这行不通,因为材料数据只是另一个播种机,将在类型播种机之前执行。由于整个 Medelfactory 都加载了 laravel,因此查询结果将为空数组。我已经在问题中提到了这一点。
    • 啊,好吧。那么为什么不简单地创建一个返回随机 id 的查询呢?
    • 我仍然必须对每个请求进行数据库查询。这就是它使播种缓慢的原因。
    猜你喜欢
    • 2015-11-29
    • 2018-08-01
    • 2011-01-18
    • 2012-08-29
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    • 2021-07-11
    • 2019-07-29
    相关资源
    最近更新 更多