如何在Eloquent中从嵌套关联筛选指定字段(Laravel 5.6)
解决Laravel Eloquent嵌套关联只返回ID的问题
嘿,我明白你的问题了!当你只在subsections的闭包里添加select('id')时返回空数组,核心原因是Eloquent需要外键字段来建立关联关系——你只选择了id,缺少了关联父模型(sections)的外键parent,导致Eloquent无法匹配对应的子模型,所以返回空数组。
下面给你两种可行的解决方案,按需选择:
方案一:查询时包含外键,通过模型隐藏控制输出
这种方式适合你希望在模型层面统一控制字段显示的场景:
- 首先修改查询代码,在
subsections的查询中同时选择id和外键parent,确保Eloquent能关联到对应的section;同时对sections只选择id字段:
public function firstSubsectionIdsOnly() { return $this->model->with(['sections' => function ($q) { $q->select('id') ->with(['subsections' => function ($q2) { // 必须包含外键parent,否则Eloquent无法关联到section $q2->select('id', 'parent') ->first(); }])->first(); }])->whereHas('sections.subsections')->first(); }
- 在你的
Subsection模型中添加隐藏字段配置,让多余的字段不会出现在JSON输出中:
class Subsection extends Model { protected $hidden = ['parent', 'created_at', 'updated_at']; }
- 同样,如果你希望
Section模型只显示id和subsections,也可以在Section模型中配置隐藏字段:
class Section extends Model { protected $hidden = ['name', 'parent', 'position', 'created_at', 'updated_at', 'pivot']; }
这样查询返回的结果就会完全符合你的预期,没有多余字段。
方案二:手动映射字段,精准控制输出
如果你不想修改模型的全局隐藏配置,可以在获取查询结果后,手动映射需要的字段:
public function firstSubsectionIdsOnly() { // 先获取完整的关联数据 $result = $this->model->with(['sections' => function ($q) { $q->with(['subsections' => function ($q2) { $q2->first(); }])->first(); }])->whereHas('sections.subsections')->first(); // 手动处理sections,只保留需要的字段 if ($result->sections) { $result->sections = $result->sections->map(function ($section) { return [ 'id' => $section->id, 'subsections' => $section->subsections->map(function ($subsection) { return ['id' => $subsection->id]; }) ]; }); } return $result; }
这种方式更灵活,能精准控制每个层级返回的字段,不会影响模型的其他查询场景。
两种方案都能实现你想要的预期结果,你可以根据自己的项目需求选择合适的方式~
内容的提问来源于stack exchange,提问作者user3574492
相关产品推荐
相关产品推荐

