Laravel Relationships HasOneThrough

时间:2016-11-26 20:12:04

标签: php laravel laravel-5

目前,我在我的模型中硬编码数据库查询来处理表关系。我想利用Laravel的Eloquent关系来代替。

我有3个模型(Property,Landlord,Tenant),它们都以某种方式相互连接。我有2个中间表(TenantProperty,LandlordProperty),它们保存了关系id。

数据透视表包含重要的contractStart / contractEnd数据,这对于未来汇款的生成至关重要。

属性表:

------------------------
|       id|   propTitle|
------------------------
|        1|  Property 1|
------------------------
|        2|  Property 2|

楼主表:

------------------------
|       id|   firstName|
------------------------
|        1|         Bob|
------------------------
|        2|       Roger|

租户表:

------------------------
|       id|   firstName|
------------------------
|        1|         Ted|
------------------------
|        2|       Peter|

TenantProperty表:

-----------------------------------------------------------------
|       id|   tenant_id|   property_id|contractStart| contractEnd
-----------------------------------------------------------------
|        1|           1|             2|   01-01-1970|  01-01-1971
-----------------------------------------------------------------
|        2|           2|             1|   01-01-1970|  01-01-1971

LandlordProperty表:

-----------------------------------------------------------------
|       id| landlord_id|   property_id|contractStart| contractEnd
-----------------------------------------------------------------
|        1|           1|             1|   01-01-1970|  01-01-1970
-----------------------------------------------------------------
|        2|           2|             2|   01-01-1973|  01-01-1973

我的问题是;是否可以hasOneThrough而不是hasManyThrough

我的模特的一个例子:

    class Tenant extends TenantModel 
    {
        public function tenantProperty() {
            return $this->hasOne('App\TenantProperty');
        }
    }

    class Property extends TenantModel
    {
        public function tenant()
        {
            return $this->hasOne('App\TenantProperty');
        }
    }

    class Landlord extends TenantModel
    {
        public function properties(){
            return $this->hasMany('App\LandlordProperty');
        }
    }

    class LandlordProperty extends TenantModel
    {
        public function property(){
            return $this->hasMany('App\Property');
        }

        public function landlord(){
            return $this->hasOne('App\Landlord');
        }
    }

    class TenantProperty extends TenantModel
    {
        public function tenant() {
            return $this->belongsTo('App\Tenant');
        }

        public function property(){
            public function product() {
                return $this->belongsTo('App\Property');
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

已编辑 - 由于您需要start_date和end_date,因此您只能明白当前属性的最后一个条目是活动属性。因此,我确信这将是处理各种可能情况的更好方法,而不是去HasManyThrough:)

landlords
id | landlord_name
---|--------------
1  |   landmine1
2  |   landmine2

tenants
id | tenant_name
---|--------------
1  |    haha
2  |    hehe
3  |    hoho

properties
id | property_name | 
---|---------------|
1  |   abc         |
2  |   abcd        |
3  |   abcde       |

landlord_property
id | property_id | landlord_id | start_date | end_date
---|-------------|-------------|------------|---------
1  |   1         |    1        |  SomeDate  | SomeDate
2  |   1         |    2        |  SomeDate  | SomeDate
3  |   2         |    1        |  SomeDate  | SomeDate

property_tenant
id | property_id | tenant_id   | start_date | end_date
---|-------------|-------------|------------|---------
1  |   1         |    1        |  SomeDate  | SomeDate
2  |   2         |    1        |  SomeDate  | SomeDate
3  |   1         |    2        |  SomeDate  | SomeDate

在这种情况下不需要中间/数据透视表

class Property extends Model
{
  public function landlords()
  {
    return $this->belongsToMany('App\Landlord');
  }

  public function tenants()
  {
    return $this->belongsToMany('App\Tenant');
  }
}

class Tenant extends Model 
{
  public function properties()
  {
    return $this->belongsToMany('App\Property');
  }

  public function landlord()
  {
    return $this->belongsTo('App\Landlord');
  }
}

class Landlord extends Model
{
  public function properties()
  {
    return $this->belongsToMany('App\Property');
  }

  public function tenants()
  {
    return $this->hasMany('App\Tenant');
  }
}

现在你可以轻松做到

$landlord = Landlord::find(1);
$propertiesOfLandlord = $landlord->properties;

$tenantsOfProperty = collect();

foreach($propertiesOfLandlord as $property) {
  $currentTenant = $property->tenants->last();
  if($currentTenant) {        
    $tenantsOfProperty->push($currentTenant);
  }
}

$property = Property::find(1);
$landlordsOfProperty = $property->landlords;
$tenantsOfProperty = $property->tenants;

$tenant = Tenant::find(1);
$propertiesOfTenant = $tenant->properties;
$landlordOfTenant = $tenant->properties()
                           // ->wherePivot('property_id', 1) If searching for a particular property of tenant
                           ->last()
                           ->landlords
                           ->last();

希望这能回答你的问题。