Laravel得到所有类别的父母

The*_*M97 7 php laravel

我在laravel中有类别和子类别

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');
    }
}
Run Code Online (Sandbox Code Playgroud)

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

@if($category->parent)
   <td>{{ $category->parent->name }} <strong>-></strong> {{ $category->name }}</td>
@else
   <td>{{ $category->name }}</td>    
@endif
Run Code Online (Sandbox Code Playgroud)

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

Des*_*901 10

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

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

    $parent = $this->parent

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

    return $parents;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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


cre*_*re8 5

您可以附加父变量:

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

    protected $appends = [
        'parent'
    ];

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

这是最短的解决方案,但这不是最好的方法,因为每次加载父对象时都会这样做。最好这样做:

class Category 扩展 Model { protected $table = 'categories';

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

在你的刀刃中你可以这样称呼:{{ $category->getParentsNames() }}


xav*_*avx 5

我知道这已经过时了,但对于未来的任何人来说,这都是正确的答案。这将为您提供无限的类别

在类别模型中

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

}
Run Code Online (Sandbox Code Playgroud)

在 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
Run Code Online (Sandbox Code Playgroud)

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