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!

9 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