Laravel“whereHas”与“take”

时间:2018-04-09 12:30:37

标签: laravel eloquent

我正在建立关系:

员工:id |名称

就业:id | employee_id | company_id | start_date | end_date | termination_type_id

一名员工可以通过时间获得许多就业机会。我需要根据就业中的最后/一个行雇用受雇的员工,这就是我失败的地方。我在我的模型Employee.php中设置了这个:

在Employee.php模型中:

public function latestEmployment() {
  return $this->hasMany(Employment::class)->orderBy('start_date', 'DESC')->take(1);
}

过滤:

$employees->where(function ($query) {
  $query->whereHas('latestEmployment', function($subquery) {
    $subquery->whereNull('termination_type_id');
  }
});

在我看来,我需要一些急切的加载,因为->take(1)不能正常工作。无论我下一步写什么,这里都考虑了整个表格。

感谢您的帮助。

编辑:

执行first()get()等在中间执行查询,因此我无法使用它。重要的是整个查询需要是一个Builder,因为我最后需要一个paginate()

2 个答案:

答案 0 :(得分:1)

最简单的解决方案是让所有员工随后过滤它们:

public function latestEmployment() {
    return $this->hasOne(Employment::class)->orderBy('start_date', 'DESC');
}

Employee::with('latestEmployment')->get()
    ->where('latestEmployment.termination_type_id', null);

仅提取相关员工的查询:

Employee::select('employees.*')
    ->join('employments', 'employees.id', 'employments.employee_id')
    ->whereNull('termination_type_id')
    ->where('start_date', function($query) {
        $query->selectRaw('max(start_date)')
            ->from('employments')
            ->whereColumn('employee_id', 'employees.id');
    })->get();

答案 1 :(得分:0)

尝试类似这样的事情

Employee::select('employees.*')->join('employments', function ($join) {
            $join->on('employees.id', '=', 'employments.employee_id')
                 ->whereNull('emails.termination_type_id');
        })->distinct()->paginate(15);