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

speedydan's avatar

Categories and Subcategories

Hey!

I'm editing a Laravel 4.3 site and I have a db table called categories which has the following fields:

  • id
  • parent_id
  • name

I'm trying to output a list in my view of categories, and their subcategories:

  • Category
  • Another Category
    • Subcat
    • Subcat
    • Subcat

I'm not really sure of the best way of achieving this and hoping someone can help point me in the right direction :-)

0 likes
10 replies
pmall's avatar

You have only one level of subcategories or many levels ?

Also 4.3 ? It is called laravel 5 now :)

speedydan's avatar

Just one level of subcategories - I meant the version before 5... my bad!

pmall's avatar

If only one level it is a simple self referencing belongs to / has many relationship.

Put a parent_id in your categories table. Then in your Category model :

public function parent()
{
    return $this->belongsTo('Category', 'parent_id');
}

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

Then you can get the subcategories of a category like this : $subcategories = $category->children.

If you want to avoid to execute one query per category to retrieve its children you can use eager loading :

$categories = Category::with('children')->get();
3 likes
MarcTroesken's avatar

And then you can loop through it like so:

@foreach($navigation as $item)
    @if($item->children->count() > 0)
        <li class="dropdown">
             <a href="#">{{ $item->name }} <span class="caret"></span></a>
             <ul>
                 @foreach($item->children as $submenu)
                     <li><a href="/{{ $submenu->slug }}">{{ $submenu->name }}</a></li>
                  @endforeach
             </ul>
       </li>
    @else
        <li><a href="/{{ $item->slug }}">{{ $item->name }}</a></li>
    @endif
@endforeach
1 like
mezie's avatar

@pmall you need to add namespace for your snippet to work. In case you tried the code and got "Class 'Category' not found", add the your namespace to it to solve the error:

public function parent()
{
    return $this->belongsTo('App\Category', 'parent_id');
}

public function children()
{
    return $this->hasMany('App\Category', 'parent_id');
}
jimmck's avatar
select * from test.menu as m
left outer join (select parent_id from test.menu where parent_id != null) as m2 
on m.parent_id = m2.parent_id

Make SQL Your Friend!

mezie's avatar

Using the snippet above, I will like to display parent category and its children under it. Something:

Fashion Accessories
  - Bags
  - Cloths
Mobile Phones
  - Tablets
  - Smartphones

How do I do such in a view

bertholf's avatar

You could also just use self::class if want to reuse the code easier...

return $this->hasMany(self::class, 'parent_id');
krekas's avatar

What about if I want to have more then one level of sub categories?

Please or to participate in this conversation.