【发布时间】:2020-12-08 21:55:20
【问题描述】:
我有一个包含类别和子项的 Laravel 项目 - 我的模型中有这个功能:
public static function tree() {
return Category::with(implode('.', array_fill(0, 100, 'children')))->where('parent_id', '=', NULL)->get();
}
然后我打电话给
$categories = Category::tree();
根据我的观点:
@foreach($categories as $index => $category)
{{ $category->title }}
@foreach($category['children'] as $child)
{{ $child->title }}
@endforeach
@endforeach
效果很好 - 但我现在正尝试按字母顺序对孩子进行排序。
我试过了:
public static function tree() {
return Category::with([implode('.', array_fill(0, 100, 'children')) => function($query) {
$query->orderBy('title', 'ASC');
}])->where('parent_id', '=', NULL)->get();
}
我也尝试过return Category::with(implode('.', array_fill(0, 100, 'children')))->where('parent_id', '=', NULL)->orderBy('title)->get();,但这只是针对父类别的订单。
但它不会对它们进行排序。有人有什么想法吗?
谢谢。
--编辑--
按照 Tim 提出的更好方法的建议,我现在有:
public function children() {
return $this->hasMany('App\Category', 'parent_id', 'id');
}
public function childrenCategories()
{
return $this->children()->with('childrenCategories');
}
那么……
$categories = Category::with(['childrenCategories' =>
function($query) {
$query->orderBy('title', 'ASC');
}])->where('parent_id', '=', NULL)->get();
哪个有效,但不是订购部分。有什么建议吗?
【问题讨论】:
-
哦,天哪……这和我想的一样吗?
with(implode('.', array_fill(0, 100, 'children')))等于children.children.children.children.children. ...因为如果是这样,那是一种非常...奇怪的无限深度递归关系的方法。 -
老实说,我不久前拿起了代码,它当时有效,但我们正在更新。我一直在看一些 Laravel 包,比如github.com/lazychaser/laravel-nestedset,这可能是一个更好的解决方案
-
哈哈是的,我理解遗留代码获取推理:P 作为参考,我用于递归关系的方法来自这个答案:stackoverflow.com/a/26654139/3965631。基本上,对
Model::with('allChildren')的一次调用将在正确设置时加载所有关系深度。它应该也允许对子模型进行正确排序(这是您问题的核心;这只是一个相当长的方法) -
谢谢蒂姆。我去看看。
-
很好 :) 但是,我认为您所拥有的不会在单次迭代之后应用排序。像
public function childrenSorted() { return $this->hasMany(Category::class, 'parent_id', 'id')->orderBy('title'); }这样的东西,然后是public function childrenCategoriesSorted(){ return $this->childrenSorted()->with('childrenCategoriesSorted'); }应该 工作。它有点冗长且有些重复,但可能会起作用。
标签: laravel eloquent laravel-7