Laravel Eager Loading如何过滤无关联子级记录的员工数据
解决方案
方案1:直接适配你期望的输出结构(推荐)
你需要的输出里没有employees嵌套层,直接在公司下关联所有符合条件的打卡记录,可以用Laravel Eloquent的hasManyThrough跨级关联实现,不需要额外处理员工过滤逻辑:
- 首先在
Company模型中定义跨级关联:
// app/Models/Company.php public function records() { return $this->hasManyThrough(Record::class, Employee::class); }
- 调整查询代码:
$companies = Company::whereIn('name', ['A', 'B']) ->with(['records' => function ($query) use ($startDate, $endDate) { $query->whereBetween('date', [$startDate, $endDate]); }]) ->get();
这个查询返回的结构完全符合你的预期,没有符合条件记录的公司records字段直接为空数组。
方案2:保留employees嵌套结构,仅过滤无有效记录的员工
如果你需要保留员工层级,只需要在员工关联的预加载逻辑中加whereHas做关联存在性校验即可:with方法仅约束关联的返回内容,不会过滤父级模型(也就是员工实例),whereHas会仅保留存在符合条件关联记录的员工:
$companies = Company::whereIn('name', ['A', 'B'])->with([ 'employees' => function ($employee) use ($startDate, $endDate) { // 过滤仅保留有符合条件records的员工 return $employee->whereHas('records', function ($record) use ($startDate, $endDate) { $record->whereBetween('date', [$startDate, $endDate]); }) // 预加载符合条件的records ->with([ 'records' => function ($record) use ($startDate, $endDate) { $record->whereBetween('date', [$startDate, $endDate]); } ]); } ])->get();
修改后没有符合条件records的员工不会出现在employees数组中。
内容的提问来源于stack exchange,提问作者user3233787
相关产品推荐
相关产品推荐

