首页 > 解决方案 > 扁平化嵌套关系按父项排序,然后是子项 - 仅靠 eloquent 可能吗?

问题描述

单独使用 eloquent 是否可能:

// build doc tree
public function tree()
{
    $docs = app(config('lap.model.doc'))->with(['children.parent', 'children' => function ($query) {
        return $query->orderBy('order');
    }])->whereNull('parent_id')->orderBy('order')->get()->toArray();

    $docs_array = [];

    foreach ($docs as $doc)
    {
        $docs_array[] = array_except($doc, 'children');

        if ($doc['children']) {
            foreach ($doc['children'] as $child) {
                $docs_array[] = $child;
            }
        }
    }

    return $docs_array;
}

只是好奇,因为尽管这种工作方式是我想要的,但我想知道是否有更好的解决方案可能已经存在于框架容量中。

标签: phplaravelrelationship

解决方案


类似这样的东西可以在 SQL 中使用:

select t.*
from t
order by coalesce(t.parent_id, t.id), `order`
;

iecoalesce当没有parent_id 时,函数使用id。这将父母和孩子的家庭“聚集”在一起,然后家庭中的行可以使用“顺序”列。

虽然我不熟悉 Laravel,但我相信可以使用orderByRaw ,如下所示:

orderByRaw('coalesce(parent_id, id), `order`')

另请参阅此答案

如果使用coalesce函数有问题,可以在 SQL 中使用此替代方法:

select t.*
from t
order by case when t.parent_id IS NULL THEN t.id else t.parent_id end, t.`order`
;

我怀疑这case expression可以转换为IFLaravel 使用的。


推荐阅读