hasManyThrough具有中间数据透视表

Mau*_*ano 4 laravel eloquent laravel-5

描述:

我的应用程序结构如下: Property与许多人有很多关系Manager,并且与a Unit有一对多关系Property,即经理可以管理多个属性,一个属性可以有多个经理帐户,一个属性可以有多个单位.

我希望在管理器上有一个HasManyThrough关系来获取他所有的单位,所以理想情况下它看起来像是:$manager->units而不是遍历每个属性并调用$property->units它.这是否可以使用当前版本的laravel?

表:

经理:

  • ID

特性:

  • ID

managers_properties:

  • MANAGER_ID
  • PROPERTY_ID

单位:

  • ID
  • PROPERTY_ID

Jef*_*amp 7

Eloquent目前没有链接关系的方法,除了hasManyThrough,只适用于2个链式hasMany关系.您应该创建自己的实现来获取相关资源.最简单的方法是在模型上定义一个访问器Manager:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Collection;

/**
 * @property-read Collection|\App\Models\Property[] $properties
 * @property-read Collection|\App\Models\Unit[] $units
 */
class Manager extends Model
{
    public function properties(): BelongsToMany
    {
        return $this->belongsToMany(Property::class);
    }

    public function getUnitsAttribute(): Collection
    {
        return $this->properties
            ->pluck('units')
            ->flatten(1)
            ->unique('id')
            ->sortBy('id');
    }
}
Run Code Online (Sandbox Code Playgroud)

您现在应该能够通过$manager->units假设访问相关单位$manager instanceof App\Models\Manager.


注意

调用$manager->units 确实在大多数n + 1数据库查询执行:1用于获取n相关属性,另一个n用于获取每个返回属性的相关单元."最多",因为之前对访问者的调用可能已经加载了资源.

注意

调用$manager->units回报你CollectionUnit型号,格式,这相当于你从多关系法的魔术访问得到什么.然而,getUnitsAttribute()不是一个实际的关系方法(它不返回一个关系对象),所以它不能被这样对待,而Manager::properties()可以.