1

I am working with Laravel data querying and I need a query that is going to group all the children of a parent when I take the categories.

the categories table has a name and a parent_id, the routes of the categories have the parent_id set as null, the query should return every category grouped by parent id and the parent should be the first node of every group.

Prafulla Kumar Sahu
  • 9,321
  • 11
  • 68
  • 105

3 Answers3

3

If you only want to display the categories as parent child somewhere, you do not need to collect them like that, you can make a relationship within the model like

class Category {
    public function children()
    {
        return $this->hasMany(self::class, 'parent_id');
    }

    public function parent()
    {
        return $this->hasMany(self::class, 'id', 'parent_id');
    }
}

may be it will be one-to-many relationship instead of many-to-many depending on your requirement.

Now you can just get all the parents like

Category::whereNull('parent_id')->get();

or using a scope

Category::parent()->get(); and define the scope in the model

and loop through the parent category like

@foreach ( $categories as $category ) 
       {{ $category->name }}
       @foreach ( $category->children as $subCategory )
           {{ $subCategory->name }}
       @endforeach
@endofreach

and to retrieve parent with children you can use

Category::whereNull('parent_id')->with('children')->get();

or

Category::parent()->with('children')->get();

I have not tested the code, but roughly it will be like this.

Prafulla Kumar Sahu
  • 9,321
  • 11
  • 68
  • 105
0

contoller

$locations   = OurLocation::groupBy('country_id')->with('children')->get();

model

public function children()
    {
        return $this->hasMany(OurLocation::class, 'country_id','country_id');
    }

blade

@foreach($locations as $index=>$location)
  @foreach($location->children as $children)
        {{ $children->company_name }} <br>
  @endforeach
@endforeach
ali hassan
  • 321
  • 2
  • 5
-2

When you get the returned collection from the query, you are able to use the ->groupBy() method where you can specify the field which the results should be grouped by.

Assuming your categories model is Category:

$categories = Category::all()->groupBy('parent_id')->toArray();
thisiskelvin
  • 4,136
  • 1
  • 10
  • 17
  • this does not return a nested collection. It groups all categories with no parent, then all categories with parent_id 1, etc. OP: `should return every category grouped by parent id and the parent should be the first node of every group` – wivku Jan 16 '20 at 16:38