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.

Like our articles?
Check out our Laravel online courses!

10 COMMENTS

  1. These approaches will only bring you so far. Any other approach, for complicated database designs? E.g. multiple relationships either way.

LEAVE A REPLY

Please enter your comment!
Please enter your name here