Eloquent递归一对多关联如何返回扁平化数组而非嵌套子关联结构
解决方案
1. 预加载关联指定字段报错修复
你遇到的Unknown column ' category'报错有两个原因:
- 字段名前多了多余的空格,系统把空格识别成了字段名的一部分
- 预加载关联时指定字段必须包含关联所需的外键
parent_id和关联表主键id,否则Eloquent无法完成父子关联的匹配
正确的预加载写法为:
Category::with('children:id,parent_id,category')->get();
2. 生成扁平化父子分类数组
你需要的父-子一一对应的扁平结构,可以用Eloquent查询后结合Laravel集合的flatMap方法实现,完全符合你只用Eloquent、不使用自定义查询构造器的要求:
一级父子匹配(适配你给出的示例格式)
如果只需要直接父分类和直接子分类的对应关系,写法如下:
$data = Category::has('children') // 过滤掉没有子分类的父分类,不需要可以删掉这行 ->with('children:id,parent_id,category') ->get() // 展开嵌套结构,生成目标格式 ->flatMap(function ($parent) { return $parent->children->map(function ($child) use ($parent) { return [ 'id' => $parent->id, 'category' => $parent->category, 'child_category' => $child->category, ]; }); }) ->toArray();
你之前直接使用flatten()达不到效果,是因为默认flatten()只会把嵌套集合的所有字段平铺,不会按照父-子对应关系组装结构。
多级递归全层级打平(适配无限级分类场景)
如果你的分类是多级递归,需要把所有层级的父子关系都打平输出,可以配合简单的递归方法实现:
// 递归处理方法 function flattenAllCategories($categories, $parent = null) { $result = collect(); foreach ($categories as $category) { if ($parent) { $result->push([ 'id' => $parent->id, 'category' => $parent->category, 'child_category' => $category->category, ]); } // 递归处理子层级 if ($category->children->isNotEmpty()) { $result = $result->merge(flattenAllCategories($category->children, $category)); } } return $result; } // 调用实现 $categories = Category::with('children:id,parent_id,category') ->whereNull('parent_id') // 从顶级分类开始遍历 ->get(); $flattenedData = flattenAllCategories($categories)->toArray();
内容的提问来源于stack exchange,提问作者Lamar
相关产品推荐
相关产品推荐

