moritzd's avatar

Eloquent grouping across relationships

Hello all,

I'm currently in the process of learning about Laravel (again) by building an e-commerce style application. I'm currently stuck on the following problem.

I have three models that are associated with each other. A manufacturer, a product and categories. The relationships are set up as follows

  • A product belongs to a category -> Category has many products
  • A product belongs to a manufacturer -> manufacturer has many products

There relationships are working as expected, but I have a problem when querying the data for the manufacturer details page. I want the manufacturer details page to show all the products built by the manufacturer, grouped by their categories so it will look like that

- manufacturer name
- manufacturer website
| - category 1
|    | - category name
|    | - products
|    |    | - product name
|    |    | - product title
|  - category 2

I have tried multiple different approaches but to no success. Can I achieve this using standard eloquent relationships or will I need to use raw queries?

I appreciate your help!

0 likes
4 replies
undeportedmexican's avatar
Level 15

@moritzd Even when the logic would say that you should call $manufacturer->products and then use that information to group them, it would actually be easier to call the categories that have products belonging to said manufacturer:

$categories = Category::with(['products' => function($query) use ($manufacturer){
	$query->where('manufacturer_id', $manufacturer->id)
}])->get();
1 like
moritzd's avatar

@undeportedmexican Thank you so much, you saved my sanity! It works!

Is there any best practice where I would place code like this? Should/can this be integrated into a relationship of the manufacturer model that I can automatically load? Or would this remain a method I'd have to call from my model manually?

undeportedmexican's avatar

@moritzd Technically you can make a HasManyThrough relationship, where you can get all the categories a manufacturer may have, and then try to make a convoluted set of maps and keys to get what you want.

In this case I would just create a productsByCategory() method on the Manufacturer model, and call it whenever you need it.

undeportedmexican's avatar

If you think the answer fit your needs please mark the issue as solved by setting a best answer 😁

Please or to participate in this conversation.