代码之家  ›  专栏  ›  技术社区  ›  Luca Cattide

Laravel 5.6-工厂关系无限播种

  •  2
  • Luca Cattide  · 技术社区  · 6 年前

    我定义了一个工厂,以便用 冒牌货 . 跟随 official docs ,我实现了如下所示:

    <?php
    
    use Faker\Generator as Faker;
    
    $factory->define(App\Item::class, function (Faker $faker) {
        return [
            'codice' => $faker->word,
            'data_acquisto' => $faker->date('Y-m-d'),
            [...] // Other stuff
            // Relations
            'componente_id' => function() {
                return factory(App\Componente::class)->create()->id;
            },
        'tipologia_id' => function() {
            return factory(App\Tipologia::class)->create()->id;
        },
        'condizione_id' => function() {
            return factory(App\Condizione::class)->create()->id;
        },
        'locazione_id' => function() {
            return factory(App\Locazione::class)->create()->id;
        },
        'fornitore_id' => function() {
            return factory(App\Fornitore::class)->create()->id;
        },
        'parent_id' => function() {
            return factory(App\Item::class)->create()->id;
        }
         ];
     });
    

    当我用 php artisan migrate:refresh --seed ,框架开始对目标表进行种子设定,但它仍停留在关系种子设定阶段。( factory(App\Componente::class)->create()->id )显然会导致某种无限/递归过程(生成数千条记录),直到任务因溢出而崩溃。

    通过谷歌搜索,我注意到许多开发人员的不同方法,但似乎其他人和我一样经历了这个问题。有人试图在工厂参数中指示最大值:

    // Ex. 5 max
    return factory(App\Componente::class, 5)->create()->id;
    

    Laravel医生没有提到。但是这样,它抛出了另一个例外:

    此集合实例上不存在属性[ID]。

    如果迁移结果如下:

    Schema::create('componente', function (Blueprint $table) {
        $table->increments('id'); // <- ID exists!
        $table->string('tipo');
        [...] // Other stuff
    }
    

    关于这一点,我阅读了收集规范,即 first() . 但我不知道如何避免这种情况。我是说,如果我用 第一个() 在语句中,如果 第一个() 只返回第一次出现的集合?

    最后,我只需要创建这一行的3行,那么我该如何接近它呢?

    提前感谢大家的帮助。

    更新

    这里是 组件工厂.php

    <?php
    
    use Faker\Generator as Faker;
    
    // Definizione dati test
    $factory->define(App\Componente::class, function (Faker $faker) {
        return [
            'tipo' => $faker->word,
            'descrizione' => $faker->optional()->sentence,
            'garanzia' => $faker->optional()->text,
            'note' => $faker->optional()->sentence
        ];
    });
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Chin Leung    6 年前

    问题来自你的 parent_id 关系。

    return factory(App\Item::class)->create()->id;
    

    由于父项是另一个项,它将创建父项,并继续在新项的父项之后创建父项,这将导致无限循环。

    要解决这个问题,可以使用随机因子来查看是否生成父级。

    例如:

    'parent_id' => function () {
        return mt_rand(0, 100) % 2 == 0 ? factory(App\Item::class)->create()->id : null;
    }
    

    因此,在生成父关系时,有50%的数据会使链停止。