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.
I personally consider factories as just a way to fill fillable attributes of a model. I take care of the relationships in the seeders.
Let's say you have two models Type
and Material
. You create two factories named TypeFactory
and MaterialFactory
. For instance TypeFactory
would be as follows:
$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 types
table, you could do:
$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.
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 pluck
method:
$materialsIds = App\Models\Material::all()->pluck('id');