Laravel Seeding: HasMany with Multiple Levels

When using seeders, the data is often interconnected: we want to seed some data with related records. Is there a "quick" syntax to do it?

If we take a look at Laravel docs, we can find this example:

1$user = User::factory()
2 ->has(Post::factory()->count(3))
3 ->create();

This example assumes that the relationship is User -> hasMany -> Posts.

What this example doesn't cover, is that you can chain this deeper, more than one level. So, let's imagine the scenario of this relationship:

1Customer -> hasMany -> Order
2 Order -> hasMany -> Product
3 Product -> hasMany -> Ingredient

And we need to seed the data for Customers, each with X orders, each order with Y products, and each product with Z ingredients.

If we have the Factory classes for those Models ready, we can write this short chain in the CustomerSeeder or even the DatabaseSeeder file:

1public function run()
2{
3 Customer::factory(100)
4 ->has(Order::factory(2))
5 ->has(Product::factory(3))
6 ->has(Ingredient::factory(5))
7 ->create();
8}

This will create 100 customers, 2 orders for each customer, 3 products for each order, and 5 ingredients for each product.

Looks like a beautiful one-liner, doesn't it?

You can read more about Laravel factories and seeding in the Laravel docs here.

No comments or questions yet...

Like our articles?

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

Written by

You might also like