Laravel 获取类别的所有父级

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45997680/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 16:35:09  来源:igfitidea点击:

Laravel get all parents of category

phplaravel

提问by TheAngelM97

I have categories and subcategories in 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');
    }
}

And I can add a new category which belongs to an already created category. Something like "Test -> subcategory of test" and then let's say I will create "sub-subcategory of test" which belongs to subcategory of test which will look like this: "Test -> subcategory of test -> sub-subcategory of test" And in the view I want to print the parents of the category if it has any. I do it like this:

我可以添加一个属于已创建类别的新类别。类似于“测试 -> 测试的子类别”,然后假设我将创建属于测试子类别的“测试的子子类别”,如下所示:“测试 -> 测试的子类别 -> 测试的子子类别" 在视图中,我想打印该类别的父级(如果有)。我这样做:

@if($category->parent)
   <td>{{ $category->parent->name }} <strong>-></strong> {{ $category->name }}</td>
@else
   <td>{{ $category->name }}</td>    
@endif

But this only shows one parent category ("subcategory of test -> sub-subcategori of test"). I want to show all the parents which will look like this: "Test->subcategory of test -> sub-subcategory of test" How can I do that?

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

回答by Desh901

You could define a model accessor on Cateorymodel that retrieves all parents and puts them into a collection. So in your Categorymodel add the following method:

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

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

    $parent = $this->parent;

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

    return $parents;
}

then in your blade template you can fetch all the parents of a category

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

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

I see no other solution different from recursively retrieving all the parents and the package suggested by @Ross Wilson in the comments. Take into account that the number of queries will be equal to the number of the parent categories.

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

Another thing that you could do is setting the parent tree into the DB in the categoriestable, to save a lot of queries. Add in your categoriestable a string field like parents_treeand at save/update time set this value with the parent names already concatenated. This is a little dirty because if one of the parents change its name you have to update all the children accordingly. Is up to you to which trade-off you want to succumb.

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

回答by cre8

you can append the parent variable:

您可以附加父变量:

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

    protected $appends = [
        'parent'
    ];

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

It's the shortest solution, but this is not the best way, since then every time a parent object is loaded. Better do this:

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

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

class Category extends 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;
    }
}

In your blade you call: {{ $category->getParentsNames() }}

在你的刀片中,你调用: {{ $category->getParentsNames() }}

回答by xavx

I know this is old but here is the correct answer for anybody in the future. This will get you unlimited categories

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

In Category Model

在类别模型

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

}

In Blade (I am sure you can do this on the model level also but here is my fast way of doing it)

在 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

Result Home / Living Room / Sofa / Couch

Result Home / 客厅 / 沙发 / 沙发