Reputation: 212
I know that I can use the hasAttached
method to create many-to-many relationships with pivot data in Laravel 8:
Meal::factory()
->count(3)
->hasAttached(Ingredient::factory()->count(3), ['gram' => 100])
->create();
Is there any convenient way (other than writing a custom for-loop) to seed the pivot table with random data for each attached entry? I want the 'gram'
to be a random number for each of the created relationships. I tried the following but the rand
expression just gets evaluated once and fills the pivot table with the same entry for each relationship:
Meal::factory()
->count(3)
->hasAttached(Ingredient::factory()->count(3), ['gram' => rand(1,100]) //not working
->create();
Edit: I basically want to achieve
for ($i = 1; $i <= 3; $i++) {
$meal = Meal::factory()->create();
for ($j = 1; $j <= 3; $j++) {
$ingredient = Ingredient::factory()->create();
$meal->ingredients()->save($ingredient, ['gram' => rand(5, 250)]);
}
}
with Laravel's fluent factory methods.
Upvotes: 7
Views: 2568
Reputation: 6058
When you call a method like this method(rand(1,100))
the rand
is evaluated before the call. It will be the same as doing method(59)
Fortunately, Laravel allow you to use a callback to re-evaluate the parameter on each call,
Meal::factory()
->count(3)
->hasAttached(Ingredient::factory()->count(3), fn => ['gram' => rand(1,100)])
->create();
If you use a PHP version bellow 7.4 you won't be able to use arrow function and you will have to do like this
Meal::factory()
->count(3)
->hasAttached(Ingredient::factory()->count(3), function () {
return ['gram' => rand(1,100)];
})
->create();
Upvotes: 14