While seeding data, it's common to have one class for each database table. But what if there are relationships? I will show you two ways you can deal with it.
Imagine we have this simple database structure - database contacts and contact_companies (taken from our Contact Management module in QuickAdminPanel):
How to seed data in both tables?
Of course, we will use Faker library, but still - there are a few ways to implement it.
First, let's define our factories.
database/factories/ContactCompanyFactory.php:
$factory->define(App\ContactCompany::class, function (Faker\Generator $faker) {
return [
'name' => $faker->name,
'address' => $faker->address,
'website' => 'https://' . $faker->word . '.com',
'email' => $faker->email,
];
});
And database/factories/ContactFactory.php:
$factory->define(App\Contact::class, function (Faker\Generator $faker) {
return [
'first_name' => $faker->firstName(),
'last_name' => $faker->lastName,
'phone1' => $faker->phoneNumber,
'phone2' => $faker->phoneNumber,
'email' => $faker->email,
'skype' => $faker->word,
'address' => $faker->address,
];
});
Now, as you can see, there's no contacts.company_id defined. Here's where we have a few options:
Version 1. Create contacts inside of company seed
Let's create a company seeder:
php artisan make:seeder CompanySeed
And then fill the file database/seeds/CompanySeed.php with this:
public function run()
{
factory(App\ContactCompany::class, 10)->create()->each(function ($company) {
$company->contacts()->save(factory(App\Contact::class)->make());
});
}
Basically, we're creating 10 companies, and for each of them we're creating one contact, using Eloquent relationship in app/ContactCompany.php:
public function contacts()
{
return $this->hasMany(Contact::class, 'company_id');
}
Version 2. Create company along with the contact
The other way around would be to use seed for Contacts.
php artisan make:seeder ContactSeed
And then add only this line in database/seeds/ContactSeed.php:
public function run()
{
factory(App\Contact::class, 10)->create();
}
You're probably wondering where the relationship would come from? We can create a "parent" entry directly in the factory! Like this:
database/factories/ContactFactory.php:
$factory->define(App\Contact::class, function (Faker\Generator $faker) {
return [
'company_id' => factory('App\ContactCompany')->create()->id,
'first_name' => $faker->firstName(),
'last_name' => $faker->lastName,
'phone1' => $faker->phoneNumber,
'phone2' => $faker->phoneNumber,
'email' => $faker->email,
'skype' => $faker->word,
'address' => $faker->address,
];
});
See the first field? We're using parent factory and creating a company "on-the-fly".
That's it, isn't it simple?
In official Laravel documentation you can find more information about seeding and using factories with Faker.
No comments or questions yet...