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

别来无恙 提交于 2019-12-03 07:46:37

You can make a self-referential model:

class Category extends Model {

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

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

and make a recursive relation:

// recursive, loads all descendants
public function childrenRecursive()
{
   return $this->children()->with('childrenRecursive');
}

and to get parents with all their children:

$categories = Category::with('childrenRecursive')->whereNull('parent')->get();

Lastly you need to just iterate through the children until children is null. There can definitely be some performance issues with this if you are not careful. If this is a fairly small dataset that you plan to remain that way it shouldn't be an issue. If this is going to be an ever growing list it might make sense to have a root_parent_id or something to query off of and assemble the tree manually.

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!

tokkerbaz

If someone needs a better answer look up my answer, it helped me, when I had faced with such a problem.

   class Category extends Model {

     private $descendants = [];

     public function children()
        {
            return $this->subcategories()->with('children');
        }

     public function hasChildren(){
            if($this->children->count()){
                return true;
            }

            return false;
        }

     public function findDescendants(Category $category){
            $this->descendants[] = $category->id;

            if($category->hasChildren()){
                foreach($category->children as $child){
                    $this->findDescendants($child);
                }
            }
        }

      public function getDescendants(Category $category){
            $this->findDescendants($category);
            return $this->descendants;
        }
 }

And In your Controller just test this:

$category = Category::find(1);
$category_ids = $category->getDescendants($category);

It will result ids in array all descendants of your category where id=1. then :

$products = Product::whereIn('category_id',$category_ids)->get();

You are welcome =)

The problem is solved!

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');
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!