如何在Laravel中创建类别的嵌套列表?

2022-08-30 22:51:42

如何在Laravel中创建嵌套的类别列表?

我想创建这样的东西:

  • --- 菲律宾比索
  • ------ 拉拉维尔
  • ---------版本
  • ------------ V 5.7
  • ---
  • ------ 詹戈
  • --- 红宝石
  • ..........

我的类别表的字段是:

id | name | parent_id

如果我必须添加另一列,如深度或其他东西,请告诉我。

我正在使用以下代码,但我认为这不是最佳解决方案。此外,我无法将此函数传递给我的视图。

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);
}

答案 1

您可以创建一个自引用模型:

class Category extends Model {

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

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

并建立递归关系:

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

并让父母和他们所有的孩子:

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

最后,您需要只循环访问子项,直到子项为 null。如果您不小心,这肯定会有一些性能问题。如果这是一个相当小的数据集,您计划保持这种状态,则应该不是问题。如果这将是一个不断增长的列表,那么从中查询或某些东西并手动组装树可能是有意义的。root_parent_id


答案 2

如果有人需要一个更好的答案来查找我的答案,当我遇到这样的问题时,它对我有所帮助。

   class Category extends Model {

     private $descendants = [];

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

     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;
        }
 }

在您的控制器中,只需对此进行测试:

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

它将在数组中生成 id,其中 id=1 的类别的所有后代。然后:

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

欢迎您 =)


推荐