You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Eager Loading如何过滤无关联子级记录的员工数据

解决方案

方案1:直接适配你期望的输出结构(推荐)

你需要的输出里没有employees嵌套层,直接在公司下关联所有符合条件的打卡记录,可以用Laravel Eloquent的hasManyThrough跨级关联实现,不需要额外处理员工过滤逻辑:

  1. 首先在Company模型中定义跨级关联:
// app/Models/Company.php
public function records()
{
    return $this->hasManyThrough(Record::class, Employee::class);
}
  1. 调整查询代码:
$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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 12:24:04