Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

tvbz's avatar
Level 4

Not sure about these relations.. How to group collection by children in eloquent?

I'm new to larevel and experimenting with some projects. I current project I am stuck on relations and eloquent model. If someone can help me to understand to way to do it?

I have 3 models with their respective tables:

car:
- id
- name

feature:
- id
- name
- group_id

featureGroup:
- id
- name

Next I also have a 4th table to create manyToMany relations between Features and Cars.

_car__feature:
- car_id
- feature_id

Now everything is working but I'm not sure how to get the Features grouped by Feature group in my Cars Controller (to show grouped features) on single car layout.

For example: Car::where('slug', $slug)->first()->load('features.group'); This returns a single car and as a child collection it's features. But here the feature group is a child of the feature. So it's car->features->featureGroup. But I want to return car->featureGroup->features, so I can loop over the featureGroups in my blade layout and return the features grouped.

How would you go about this in Eloquent? Or am I thinking the wrong way, should I somehow set a relationship to featureGroups() inside the Car model, instead of features()?

Thanks

0 likes
3 replies
amjadAH's avatar
amjadAH
Best Answer
Level 3

Try this:

$car->features->groupBy('group_id');

this should return something like this:

{
  "id": 1,
  "name": "BMW",
  "features": {
    "2": [ // "2" is the group id
      {
        "id": 3,
        "name": "feature 1",
        "group_id": 2
      },
      {
        "id": 4,
        "name": "feature 2",
        "group_id": 2
      }
    ],
    "3": [ // "3" is the group id
      {
        "id": 5,
        "name": "feature 3",
        "group_id": 3
      },
      {
        "id": 6,
        "name": "feature 4",
        "group_id": 3
      }
    ]
  }
}
1 like
tvbz's avatar
Level 4

Oh man @amjad_ah thank you! Didn't realize there was a method for this. Laravel rocks! :)

1 like
tvbz's avatar
Level 4

I found different solution using mapToGroups(). I prefer this one because it cleans up output some more and gets only the thing I need from the collection and nothing else. Posting it here for others and my own future reference:

In controller:

$details = $car->features->mapToGroups(function ($item, $key) {
      return [$item['group']['name'] => $item['name']];
});

Output:

{
    "group 1": [
        "feature 1",
        "feature 2"
    ],
    "group 2": [
        "feature 3",
        "feature 4",
        "feature 5"
    ]
}

This way it's very easy to render in blade component/layout:

@foreach ($details as $key => $value)
    <h3>{{ $key }}</h3>
    <ul>
        @foreach ($value as $feature)
            <li>{{ $feature }}</li>
        @endforeach
    </ul>
@endforeach

Hope it can be helpfull for others with similar issue. Cheers!

1 like

Please or to participate in this conversation.