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

webfuelcode's avatar

Subcategory list with its parent category

Trying to list parent category and few subcategories of it. I have one table and it has both categories and subcategories.

category

The controller is something like this:

public function posts()
    {
        $posts = Post::latest()->take(5)->get();
        $cats = Category::where('parent_id', NULL)->latest()->take(5)->get();
        $subcats = Category::where('parent_id', '=', 'id')->take(5)->get();
        return view('welcome', compact('posts', 'cats', 'subcats'));
    }

The view is experimental and not complete

<div class="row">
            @forelse ($cats as $cat)
                <div class="col-md-4">
                    <div class="card">
                        <div class="card-body">
                            {{ $cat->name }}
                            
                        </div>
                    </div>
                </div>
            @empty
                <div class="card">
                    <div class="card-body">
                        There are no posts available yet.
                    </div>
                </div>
            @endforelse
        </div>
0 likes
4 replies
gitwithravish's avatar

So you are dealing with recursive relationship. You can define the relation within your model and access the sub categories using with method while querying the table.

However, since you are a subscriber to laracasts, I will suggest you to take a look at the following video. It will help you understand the concept.

https://laracasts.com/series/how-do-i/episodes/9

1 like
gitwithravish's avatar

assuming that you have only one level of subcategories...

$parentCategoryID = 1;

Category::with('children.posts')->where('id',$parentCategoryID)->get();

1 like
KalimeroMK's avatar

Edit tis code for you needs

Database Migration Here’s a simple schema of DB table:

Schema::create('categories', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->string('name');
    $table->unsignedBigInteger('category_id')->nullable();
    $table->foreign('category_id')->references('id')->on('categories');
    $table->timestamps();
});

We just have a name field, and then relationship to the table itself. So most parent category will have category_id = NULL, and every other sub-category will have its own parent_id.

Here’s our data in the database:

Eloquent Model and Relationships First, in app/Category.php we add a simple hasMany() method, so category may have other subcategories:

class Category extends Model
{

    public function categories()
    {
        return $this->hasMany(Category::class);
    }

}

Now comes the biggest “trick” of the article. Did you know that you can describe recursive relationship? Like this:

public function childrenCategories()
{
    return $this->hasMany(Category::class)->with('categories');
}

So, if you call Category::with(‘categories’), it will get you one level of “children”, but Category::with(‘childrenCategories’) will give you as many levels as it could find.

Route and Controller method Now, let’s try to show all the categories and subcategories, as in the example above.

In routes/web.php, we add this:

Route::get('categories', 'CategoryController@index');
Then, app/Http/CategoryController.php looks like this:

public function index()
{
    $categories = Category::whereNull('category_id')
        ->with('childrenCategories')
        ->get();
    return view('categories', compact('categories'));
}

As you can see, we’re loading only parent categories, with children as relationships. Simple, huh?

View and Recursive Sub-View Finally, to the Views structure. Here’s our resources/views/categories.blade.php:

<ul>
    @foreach ($categories as $category)
        <li>{{ $category->name }}</li>
        <ul>
        @foreach ($category->childrenCategories as $childCategory)
            @include('child_category', ['child_category' => $childCategory])
        @endforeach
        </ul>
    @endforeach
</ul>

As you can see, we load the main categories, and then load children categories with @include.

The best part is that resources/views/admin/child_category.blade.php will use recursive loading of itself. See the code:

<li>{{ $child_category->name }}</li>
@if ($child_category->categories)
    <ul>
        @foreach ($child_category->categories as $childCategory)
            @include('child_category', ['child_category' => $childCategory])
        @endforeach
    </ul>
@endif

As you can see, inside of child_category.blade.php we have @include(‘child_category’), so the template is recursively loading children, as long as there are categories inside of the current child category.

And, that’s it! We have unlimited level of subcategories – in database, in Eloquent relationships, and in Views.

1 like

Please or to participate in this conversation.