Larevel users lets say you have three models User, Store and Product, and both Store and Product have a user_id foreign key to the users table, your Product factory may look like this:
<?php
//ProductFactory.php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\Product;
use Faker\Generator as Faker;
$factory->define(Product::class, function (Faker $faker) {
return [
'name' => $faker->productName,
'description' => $faker->text(),
'price' => $faker->randomNumber(4),
'sku' => $faker->uuid,
'user_id' => function() {
return factory(\App\User::class)->create()->id;
},
'store_id' => function() {
return factory(\App\Store::class)->create()->id;
}
];
});
And your StoreFactory like this:
<?php
//StoreFactory.php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\Store;
use Faker\Generator as Faker;
$factory->define(Store::class, function (Faker $faker) {
return [
'name' => $faker->city,
'location' => 'SRID=4326;POINT(-74.069891 4.605246)',
'address' => $faker->address,
'user_id' => function(){
return create(\App\User::class)->id;
},
'code' => 'S' . $faker->randomNumber(5)
];
});
The problem is that then when generating products, the store they belong to doesn't belongs to the same user, and that makes no sense, these three models are just an example the same logic is valid for your specific database model, the solution is to access the current instance generated fields in the callback of the foreign key is:
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\Product;
use Faker\Generator as Faker;
$factory->define(Product::class, function (Faker $faker) {
return [
'name' => $faker->productName,
'description' => $faker->text(),
'price' => $faker->randomNumber(4),
'sku' => $faker->uuid,
'user_id' => function() {
return create(\App\User::class)->id;
},
'store_id' => function(array $product) {
return factory(\App\Store::class)->create(['user_id' => $product['user_id']])->id;
}
];
});
The callback argument array $product
has the current instance fields, this way you can pass the dynamic generated User to the "sibling" Store model.
Hope it is useful!.
Top comments (3)
Thank you for the tips.
Nice I've never thought you could pass a function as the value of an element in the factories
Yeah, it saves a lot of repetition or helper functions