Laravel得到所有类别的父母

时间:2017-09-01 09:58:03

标签: php laravel

我在laravel中有类别和子类别

if(params.page==1)
return {"total":12, "root" : [{
   "Surname": "lisa",
   "Name":"King",
   "RollNo": 1
  },
  {
   "Surname": "John",
   "Name":"Lever",
   "RollNo": 2
  },
  {
   "Surname": "Lee",
   "Name":"Dev",
   "RollNo": 3
  }]};
else if(params.page == 2) 
...

我可以添加属于已创建类别的新类别。像“测试 - >测试的子类别”之类的东西,然后让我说我将创建属于测试的子类别的“测试的子子类别”,它将如下所示:“测试 - >测试的子类别 - >子 - 测试子类别“ 在视图中,我想打印该类别的父母,如果有的话。 我是这样做的:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    protected $table = 'categories';

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

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

但这仅显示一个父类别(“测试的子类别 - >测试子类别”)。我想展示所有看起来像这样的父母:“测试 - >测试的子类别 - >测试子类别” 我怎么能这样做?

5 个答案:

答案 0 :(得分:9)

您可以在Cateory模型上定义模型访问器,以检索所有父项并将它们放入集合中。因此,在Category模型中添加以下方法:

public function getParentsAttribute()
{
    $parents = collect([]);

    $parent = $this->parent

    while(!is_null($parent)) {
        $parents->push($parent);
        $parent = $parent->parent;
    }

    return $parents;
}

然后在您的刀片模板中,您可以获取某个类别的所有父母

@if(count($category->parents))
    <td>{{ $category->parents->implode('-') }} <strong>-></strong> {{ $category->name }}</td>
@else
    <td>{{ $category->name }}</td>
@endif

我认为没有其他解决方案与评论中递归检索@Ross Wilson建议的所有父母和包的情况不同。考虑到查询的数量将等于父类别的数量。

您可以做的另一件事是将父树设置到categories表中的数据库中,以节省大量查询。在categories表中添加一个字符串字段parents_tree,并在保存/更新时将此值设置为已连接的父名称。这有点脏,因为如果其中一个父母改名,你必须相应地更新所有孩子。由你来决定你想要屈服于哪种权衡。

答案 1 :(得分:1)

你可以附加父变量:

class Category extends Model
{
    protected $table = 'categories';

    protected $appends = [
        'parent'
    ];

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

它是最短的解决方案,但这不是最好的方法,因为每次加载父对象时都是如此。更好地做到这一点:

class Category扩展Model {     protected $ table =&#39; categories&#39;;

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

public function getParentsNames() {
    if($this->parent) {
        return $this->parent->getParentsNames(). " > " . $this->name;
    } else {
        return $this->name;
    }
}

在您的刀片中,您可以致电:{{ $category->getParentsNames() }}

答案 2 :(得分:1)

我知道这很老了,但这是将来任何人的正确答案。这将为您提供无限的类别

在类别模型中

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

public function getParentsNames() {

    $parents = collect([]);

    if($this->parent) { 
        $parent = $this->parent;
        while(!is_null($parent)) {
            $parents->push($parent);
            $parent = $parent->parent;
        }
        return $parents;
    } else {
        return $this->name;
    }

}

在Blade中(我相信您也可以在模型级别执行此操作,但这是我快速执行此操作的方法)

 @if ($category->getParentsNames() !== $category->name)
                                @foreach ($category->getParentsNames()->reverse() as $item)
                                    @if ($item->parent_id == 0)
                                        <li class="breadcrumb-item"><a href="/{{ $item->slug }}">{{ $item->name }}</a></li>
                                             @else
                                        <li class="breadcrumb-item"><a href="../{{ $item->slug }}">{{ $item->name }}</a></li>
                                    @endif
                                @endforeach  
                            @endif

结果首页/客厅/沙发/长沙发

答案 3 :(得分:0)

我只注意到进入主类别,也许它对某人有用。

 static function  getDepth($parent_id) {

       $categories= Categories::find($parent_id);

       if ($categories) {
           if ($categories->parent_id == 0) {
               return $categories->category_name;
           } else {
               return self::getDepth($categories->parent_id);
           }
       }

    }

blade.php

   <td>{{ \App\Models\Admin\Category::getDepth($category->parent_id)}}</td>

答案 4 :(得分:0)

到目前为止,我发现的最佳解决方案是使用嵌套集模型
详细的解释/实现已经很长时间了,并且已经有很多关于它的主题。所以我会缩短主题。

这个想法是用父值之间的值对类别进行分组,依此类推。 例如:

Clothes : 1-10
    - T-shirts: 2-3
    - Pants: 4-9
        - Shorts 5-6
        - Joggers 7-8

使用这些值,只需使用一个查询就可以很容易地查询所有的祖先或后代类别,因为它们总是包含在两个值之间。

一个主要的缺点是;当类别发生变化(创建/删除/移动)时,需要重新评估和更新节点。


这是(IMO)我找到的最佳解释:http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

我还发现这个库似乎运行良好https://github.com/lazychaser/laravel-nestedset