Laravel: Two Ways to Seed Data with Relationships

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): contact management laravel 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 yet…

Like our articles?

Become a Premium Member for $129/year or $29/month

Written by