Laravel雄辩的一个模型和许多模型之间的关系为MorphOne?

时间:2018-06-11 03:33:43

标签: php laravel eloquent relationship polymorphic-associations

简介

我有这些表格及其模型:

  • 地址表 - >地址模型
  • 用户表 - >用户模型
  • 公司表 - >公司模式
  • 属性表 - >物业模型

规则:

  • 每个用户只能拥有一个地址。
  • 每家公司只能有一个地址。
  • 每个Property只能有一个地址。

可以在此处完成两种可能的关系规划:

  • 用户 hasOne 地址和地址 belongsTo 用户[即一对一的关系],但缺点是这里的外键位于地址表即 user_id 字段,并通过与其他模型[公司和财产]重复相同的关系,我们将获得另外两个地址表中的外键是[ company_id property_id ],那么我们最终将为3个模型提供3个外键但 只有一个将每行填写 记录,留下总是两个外键字段留空

    我觉得这是地址表的间接费用。

或者相反:

  • 地址 hasOne 用户和用户 belongsTo 地址[一对一关系也]。这样做的好处是它将外键保存在相关的模型中,即[用户,公司和财产],这样就没有外键的空字段---但这仍然违背现实生活中的建模逻辑,它决定了< strong> 用户 hasOne地址超过 地址 hasOne用户。

我的问题:

是否有任何其他关系可以将这4个模型绑定在一个类似于多态关系的关系中,但不使用 MorphMany ,而是使用 MorphOne 奇怪的是,我在Laravel的文档中找不到它,尽管该方法本身存在于Eloquent Relations中。

MorphOne 多态关系是否可能及其组成方式?

现有代码:

//Address model
public function user(){
    return $this->hasOne(User::class);
}
public function company(){
    return $this->hasOne(Company::class);
}
public function property(){
    return $this->hasOne(Property::class);
}

//User model
public function address(){
    return $this->belongsTo(Address::class);
}

//Company model
public function address(){
    return $this->belongsTo(Address::class);
}
//Property model
public function address(){
    return $this->belongsTo(Address::class);
}

1 个答案:

答案 0 :(得分:7)

以下是 地址 用户 之间的MorphOne关系另一方的公司 财产

class Address extends Model
    public function addressable(){
        return $this->morphTo();
    }       
}

class User extends Model
    public function address(){
        return $this->morphOne(Address::class,'addressable'); //note this is not MorphMany()
    }       
}

class Company extends Model
    public function address(){
        return $this->morphOne(Address::class,'addressable');
    }       
}

class Property extends Model
    public function address(){
        return $this->morphOne(Address::class,'addressable');
    }       
}

然后在 UserController 之类的东西:

$user = User::find(1);

$addressData = [
    'street_name' => '5, Golf street',
    'country_id' => 100, //etc..
];

//to add new address record related to user:
$user->address()->create($addressData);
dd($user->address);

//to update existing address record related to user:
$user->address->update($addressData);
//dd($user->address);