一个模型和多个模型之间的 Laravel Eloquent 关系作为 MorphOne?

Posted

技术标签:

【中文标题】一个模型和多个模型之间的 Laravel Eloquent 关系作为 MorphOne?【英文标题】:Laravel Eloquent relationship between one Model and Many Models as MorphOne? 【发布时间】:2018-11-20 06:14:08 【问题描述】:

简介:

我有这些表及其模型:

地址表 --> 地址模型 用户表 --> 用户模型 公司表 --> 公司模型 属性表 --> 属性模型

规则:

每个用户只能有一个地址。 每个公司只能有一个地址。 每个属性只能有一个地址。

这里可以进行两种可能的关系规划:

用户hasOne地址和地址belongsTo用户[即一对一的关系],但缺点是这里的外键位于地址表即user_id字段中,通过与其他模型[公司和财产]重复相同的关系,我们将得到另外两个地址表中的外键分别是 [company_idproperty_id],那么我们将得到 3 个模型的 3 个外键但是 只有一个会由每一行填充 记录总是留下两个外键字段留空

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

或者反过来:

地址hasOne用户和用户belongsTo地址[也是一对一的关系]。这样做的好处是,它将外键保留在相关模型中,即[用户、公司和财产],这样就没有外键的空字段——但这仍然违背了现实生活中的建模逻辑,它规定 User hasOne Address 多于 Address hasOne User。

我的问题:

是否有任何其他关系可以将这 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);

【问题讨论】:

如何在地址表中保存一个 id 和 type 字段。这里的 id 将是来自用户、公司或属性表的 id,类型将存储该 id 所属的名称(用户/公司/属性)。我不确定如何使用 eloquent 实现这一目标 可以将类型字段保存为枚举 我同意你的观点,因为这看起来与我正在搜索的 MorphOne 关系相同。但我会为此使用 Eloquent 而不是手动进行 - 这是为了利用内置的 Eloquent 关系而不是我自己手动构建 setter 和 getter。 我主要关心的是建立关系而不是存储数据本身,因为我可以直接在 Laravel 中通过 AddressController 限制数据存储的值和类型。我所追求的是 Address 与其他 3 个模型 User、Company 和 Property 之间的 Eloquent 正确关系,以便在进一步的项目代码中使用它。 【参考方案1】:

这是一侧的 AddressUser 之间的 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);

【讨论】:

以上是关于一个模型和多个模型之间的 Laravel Eloquent 关系作为 MorphOne?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.6 - “试图获取非对象的属性”

Laravel Eloquent 关系与多个带有“OR”的外键

Laravel 混合获取 Eloquent 急切加载嵌套多个模型

Laravel 数据库模型自身之间的关系

Laravel Eloquent 模型使用多个表合并为一个(没有单独的模型)

Laravel - 我有一个具有不同角色的用户模型。如何在具有特定角色的用户之间建立关系? [关闭]