How to create a nested-list of categories in Laravel?

Viewed 16606

How can I create a nested list of categories in Laravel?

I want to create something like this:

  • --- Php
  • ------ Laravel
  • --------- Version
  • ------------ V 5.7
  • --- Python
  • ------ Django
  • --- Ruby
  • ..........

The fields of my categories table are:

id | name | parent_id

If I have to add another column like depth or something, please tell me.

I am using this following code, but I think it is not the best solution. Besides, I can not pass this function to my view.

function rec($id)
{
     $model = Category::find($id);
     foreach ($model->children as $chield) rec($chield->id);
     return $model->all();
}

function main () {
    $models = Category::whereNull('parent_id')->get();
    foreach ($models as $parent) return rec($parent->id);
}
6 Answers

This function will return tree array:

function getCategoryTree($parent_id = 0, $spacing = '', $tree_array = array()) {
    $categories = Category::select('id', 'name', 'parent_id')->where('parent_id' ,'=', $parent_id)->orderBy('parent_id')->get();
    foreach ($categories as $item){
        $tree_array[] = ['categoryId' => $item->id, 'categoryName' =>$spacing . $item->name] ;
        $tree_array = $this->getCategoryTree($item->id, $spacing . '--', $tree_array);
    }
    return $tree_array;
}

Searching for something somehow in this area I wanted to share a functionality for getting the depth level of child:

    function getDepth($category, $level = 0) {
    if ($category->parent_id>0) {
        if ($category->parent) {
                $level++;
                return $this->getDepth($category->parent, $level);
            }
        }
       return $level;
    }

Maybe it will help someone! Cheers!

you can solve this problem like this :

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

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

}

and get category with children like this :

Category::whereNull('category_id')
    ->with('childrenCategories')
    ->get();

notice : just rename parent_id column to category_id

This also worked:

View:

    $traverse = function ($categories) use (&$traverse) {
        foreach ($categories as $category) $traverse($cat->Children);
    };
    $traverse(array ($category));

Model:

public function Children()
{
    return $this->hasMany($this, 'parent');
}

public function Parent()
{
    return $this->hasOne($this,'id','parent');
}
Related