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

如何让Laravel Eloquent的inheritedEmployees返回Eloquent关联关系?

解决方法:让inheritedEmployees返回Eloquent关联关系

要让这个方法返回可链式调用的Eloquent关联(而非集合),我们需要利用Eloquent的查询构造器能力,通过嵌套关联查询直接获取符合条件的员工,替代原来循环拼接集合的方式。这样既能避免N+1查询的性能问题,又能支持后续追加任意查询条件。

步骤1:替换原方法代码

在Office模型中把inheritedEmployees方法改成如下实现:

// Office model
public function inheritedEmployees()
{
    // 如果是大型办公室(major),直接返回空的查询构造器
    if ($this->is_major) {
        return \App\Model\Employee::query()->whereDoesntExist();
    }

    // 构建关联查询:获取当前小型办公室关联的所有大型办公室下的员工
    return \App\Model\Employee::query()
        ->whereHas('offices', function ($officeQuery) {
            // 筛选出与当前小型办公室绑定的大型办公室
            $officeQuery->whereHas('minors', function ($minorQuery) {
                $minorQuery->where('minors.id', $this->id);
            });
        })
        ->distinct(); // 去重,避免同一员工属于多个大型办公室时重复返回
}

为什么这样改?

  • 返回可链式的构造器:现在这个方法返回的是Illuminate\Database\Eloquent\Builder实例,和你用$office->employees()得到的关联类型完全一致,支持所有Eloquent查询方法(where、orderBy、with等)。
  • 性能大幅提升:原方法是循环每个大型办公室并加载其员工,属于典型的N+1查询;新方法通过一次嵌套查询完成所有操作,数据库请求次数大幅减少。
  • 逻辑完全对齐:distinct()替代了原方法的unique('id'),确保员工不会重复返回;whereDoesntExist()保证大型办公室返回空结果,和原逻辑保持一致。

使用示例

现在你可以像使用普通关联一样自由追加查询条件了:

// 筛选继承员工中职位为医生或牙医的
$qualifiedInherited = $minorOffice->inheritedEmployees()->whereHas('qualifications', function ($query) {
    $query->whereIn('job', ['doctor', 'dentist']);
})->get();

// 还可以排序、关联预加载
$sortedInherited = $minorOffice->inheritedEmployees()
    ->orderBy('first_name')
    ->with('qualifications')
    ->get();

内容的提问来源于stack exchange,提问作者DatsunBing

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 03:48:33