我在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');
}
}
但这仅显示一个父类别(“测试的子类别 - >测试子类别”)。我想展示所有看起来像这样的父母:“测试 - >测试的子类别 - >测试子类别” 我怎么能这样做?
答案 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