Laravel / Eloquent模型,包含多对多和自引用

时间:2018-05-16 01:42:23

标签: laravel eloquent

办公室有很多员工,员工可以在很多办公室工作。

// office model
public function employees()
{
    return $this->belongsToMany(Model\Employee::class);
}

// employee model
public function offices()
{
    return $this->belongsToMany(Model\Office::class);
}

使用这个我可以得到一个关系,进一步过滤如下:

$qualified = $office->employees()->whereHas('qualifications', function ($query) {
    $query->whereIn('job', ['doctor', 'dentist']);
});

困难在于一些办公室太小而无法拥有自己的员工,因此我们将它们“附加”到一个或多个大型办公室,并让他们“继承”该员工。我们将小型办公室称为“未成年人”,将大型办公室称为“专业”。

// office model
public function majors() {
    return $this->belongsToMany(Model\Office::class, 'attachments', 'minor_id', 'major_id');
}

在处理一个小型(即“未成年人”)办公室时,我需要能够访问他们继承的员工。我设法做到如下:

// office model
public function inheritedEmployees()
{
    $employees = collect();
    if ($this->is_major) return $employees;

    foreach ($this->majors as $major) {
        $employees->concat($major->employees);
    }

    return $employees->unique('id')->sortBy('first_name');
}

问题是inheritedEmployees()没有返回Eloquent Relationship,因此我无法为其添加额外的子句。

如何更改inheritedEmployees()以恢复关系?

1 个答案:

答案 0 :(得分:1)

您不需要实际返回关系以将方法链接到它;任何尚未执行的查询都将返回您可以链接的QueryBuilder

假设您有反向minors()关系(取得主要办公室下的办公室),您可以尝试这样做:

// In the Office model

public function inheritedEmployees() {
    return EmployeeAssignment::query()
                ->where('office_id', $this->minors()->pluck('id'));
}

我假设你创建了一个帮助器(EmployeeAssignment)类来为办公室和员工之间的数据透视表建模(这对处理复杂的关系很有用)。