Laravel如何获取同一表中指定ID的多级关联子行?
解决多级嵌套文件管理器的子记录查询问题
你的sub()关联方法只能获取直接子记录,无法递归获取多级嵌套的所有子项,以下是两种可行的解决方案:
方法一:递归关联+收集子记录
先修改关联方法,添加递归加载子级关联:
public function sub() { return $this->hasMany(FileManager::class, 'parent_id')->with('sub'); }
然后通过递归函数收集所有层级的子记录:
// 获取目标父级记录 $parent = FileManager::find(1); // 递归收集所有子项 function collectAllChildren($model) { $children = $model->sub; foreach ($children as $child) { $children = $children->merge(collectAllChildren($child)); } return $children; } // 所有子记录集合 $allChildren = collectAllChildren($parent);
方法二:数据库递归查询(推荐,性能更优)
如果你的数据库支持CTE(比如MySQL 8+、PostgreSQL),可以直接用递归SQL查询,避免N+1查询问题:
$parentId = 1; $allChildren = FileManager::select('*') ->fromRaw('( WITH RECURSIVE file_tree AS ( -- 起始节点:直接子记录 SELECT id, uuid, name, parent_id FROM file_managers WHERE parent_id = ? -- 递归拼接子级 UNION ALL SELECT fm.id, fm.uuid, fm.name, fm.parent_id FROM file_managers fm JOIN file_tree ft ON fm.parent_id = ft.id ) SELECT * FROM file_tree ) AS sub', [$parentId])->get();
原关联失效原因
你定义的hasMany仅建立了一级父子关联,没有指定递归加载子级的子关联,所以只能查询到直接子记录,无法覆盖多级嵌套的场景。
内容的提问来源于stack exchange,提问作者muntasir
相关产品推荐
相关产品推荐

