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.
Assuming that you have Users and Addresses, you may do the the 2nd option. This is pretty simple and easy.
Great article!
I have a question, do you need to get the id like this:
‘company_id’ => factory(‘App\ContactCompany’)->create()->id,
Sorry, yes, fixed the article. Thanks!
hello please do you have any articles on image resizing in laravel? maybe using cloudinary api or so. i’m trying to resize all images uploaded by users of my site to the same size.
Good article. I am following the second approach. Good to know I was on the right path 🙂
Great, but what if we want to make 3 comments for each user with faker ??
thank you 🙂
Then you add a number factory(App\Comment::class, 3)->create() where needed.
@Povilas Korop , I have tried but I am getting error
Use SaveMany instead of Save + the number of desired occurrence as mentioned above.
These approaches will only bring you so far. Any other approach, for complicated database designs? E.g. multiple relationships either way.
You can also do this if you use Laravel . 6.x
factory(User::class)->create()->id
This helped me to figure out my issue, but Laravel has been more smarter now a days. Thanks for keeping this resource.
The article was helpful. Thank you
You can just write:
‘company_id’ => factory(‘App\ContactCompany’)
Instead of the full:
‘company_id’ => factory(‘App\ContactCompany’)->create()->id,