Reputation:
I defined a factory in order to seed tables with faker. Following the official docs, I implemented it as showed, like this:
<?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;
}
];
});
When I launch it with php artisan migrate:refresh --seed
, framework starts to seed the destination tables, but it being stuck in the relation seeding phase (factory(App\Componente::class)->create()->id
). Apparently resulting in a some sort of infinite/recursive process (generating thousands of records), until the task crashes due to an overflow.
By googling around, I noticed different approaches from many devs, but seems that others experienced this problem like me. Someone tried to indicate the max number in the factory argument:
// Ex. 5 max
return factory(App\Componente::class, 5)->create()->id;
And the Laravel doc doesn't mention it. But in this way, it throws another exception:
Property [id] does not exist on this collection instance.
Either if the migration results like this:
Schema::create('componente', function (Blueprint $table) {
$table->increments('id'); // <- ID exists!
$table->string('tipo');
[...] // Other stuff
}
About this, I read about the collection specification, i.e. the use of first()
. But I don't get how to avoid this scenario. I mean, if I use first()
in the statement, how can it generates the number of required rows if first()
returns only the first collection occurrence?
At last, I just need to create 3 rows of this one, so how can I approach it?
Thanks in advance everyone for help.
UPDATE
Here's ComponenteFactory.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
];
});
Upvotes: 2
Views: 904
Reputation: 14921
The problem comes from your parent_id
relationship.
return factory(App\Item::class)->create()->id;
Since the parent is another item, it will create a parent and keep going on creating parents after parents for the new items, which will cause an infinite loop.
To fix this, you may use a random factor to see if you generate a parent or not.
For example:
'parent_id' => function () {
return mt_rand(0, 100) % 2 == 0 ? factory(App\Item::class)->create()->id : null;
}
Therefore, when generating the parent relationship, there's a 50% that it will stop the chain.
Upvotes: 1