【问题标题】:Laravel: many-to-many with shared tableLaravel:多对多共享表
【发布时间】:2015-05-09 12:33:39
【问题描述】:

我有 Locations 模型,其中有很多 Employees -- 同样是 Employees 属于Locations

这很好,效果很好,但后来我考虑添加PhoneNumbers任一LocationEmployee 都可以有电话号码(办公室号码与个人号码)

逻辑上:

LocationshasMany PhoneNumbers(多条办公线路) 和 Employees hasMany PhoneNumbers(家庭/手机?)

但是,当您在 Laravel 中创建这样的 hasMany 关系时,它会在 PhoneNumbers 表中添加一个字段。所以我们现在有两个字段:location_idemployee_id

如果我将location_idemployee_id 设为可空,我可以让它工作,如下所示:

+----+--------------+-------------+-------------+
| id |    number    | location_id | employee_id |
+----+--------------+-------------+-------------+
|  1 | 800-555-0123 |      1      |     null    |
|  2 | 800-555-0124 |      1      |     null    |
|  3 | 800-555-0125 |      1      |     null    |
|  4 | 859-555-0199 |     null    |       1     |
                     ...

但是,如果我添加可以拥有电话号码的新实体(客户?求职者?供应商?),这不会很好地扩展

如何使用同一个辅助表创建多个单独的多对多关系?

注意:在此示例中,我可以在每个单独的表(locations.phone_numberemployees.phone_number 等)上创建一个 phone_number 字段,但我希望避免这种情况有两个原因:

  1. 数据完整性(如果所有电话号码都在一个公用表中,则很容易验证没有输入重复的电话号码)
  2. 绑定到更复杂的模型(将PhoneNumber 替换为Image,现在您需要处理更多数据)

【问题讨论】:

  • 一切都记录在案,为什么还要写一个问题。
  • 因为如果您不知道正确的术语,那么文档对您没有好处。我可以整天在谷歌上搜索“与不同表的多对多关系”,但我永远找不到“多态”这个词
  • 多态关系允许一个模型在一个关联上属于多个其他模型。例如,您可能有一个属于员工模型或订单模型的照片模型。 直接来自文档...我只是想指出这已经很好地记录了,我不想要粗鲁之类的。

标签: php mysql laravel many-to-many relationship


【解决方案1】:

你正在寻找 Laravel 的多态关系。您不必为每个相关表创建一个新字段,而是有两个字段:相关 id 和相关类型。

在您的 Location 和 Employee 模型上,添加以下关系:

public function phones()
{
    return $this->morphMany('PhoneNumber', 'phonable');
}

在您的 PhoneNumber 模型上,添加以下关系:

public function phonable()
{
    return $this->morphTo();
}

在您的 phone_numbers 表中,添加两个新字段:phonable_type 和 phonable_id。在迁移中,这些字段通过morphs() 方法添加:$table->morphs('phonable');

一切都设置好后,您的数据将如下所示:

+----+--------------+-------------+---------------+
| id |    number    | phonable_id | phonable_type |
+----+--------------+-------------+---------------+
|  1 | 800-555-0123 |      1      |    Location   |
|  2 | 800-555-0124 |      1      |    Location   |
|  3 | 800-555-0125 |      1      |    Location   |
|  4 | 859-555-0199 |      1      |    Employee   |
                     ...

使用此设置,您可以通过添加morphOne()morphMany() 关系来制作您想要的任何模型phonable

此外,关系属性将生成与类型相关的正确模型。鉴于以上数据:

var_dump(PhoneNumber::find(1)->phonable); // will dump Location object
var_dump(PhoneNumber::find(4)->phonable); // will dump Employee object

有关多态关系的文档可以在here (4.2)here (5.0) 找到。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-10
    • 2011-01-15
    • 2012-07-22
    • 2018-08-26
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多