代码之家  ›  专栏  ›  技术社区  ›  stevendesu

Laravel:多对多共享餐桌

  •  2
  • stevendesu  · 技术社区  · 9 年前

    我有 Locations 具有多个 Employees --类似地 员工 属于 位置

    这很好,效果也很好,但后来我看到了添加 PhoneNumbers . 任何一个 Location Employee 可能有电话号码(办公室号码与个人号码)

    逻辑上:

    位置 有很多 电话号码 (多条办公线路) 和 员工 有很多 电话号码 (家庭/手机?)

    然而,当你在Laravel中创建这样的hasMany关系时 电话号码 桌子所以我们现在有了 领域: location_id employee_id

    如果我能 位置_id 雇员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     |
                         ...
    

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

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

    注: 在这个例子中,我可以创建一个 phone_number 每个表上的字段( locations.phone_number , employees.phone_number ,等等)但是,出于两个原因,我希望避免这种情况:

    1. 数据完整性(如果所有电话号码都在一个公共表中,则很容易验证是否输入了重复的电话号码)
    2. 绑定到更复杂的模型(替换 PhoneNumber 具有 Image 现在你有更多的数据要处理)
    1 回复  |  直到 9 年前
        1
  •  3
  •   patricus    9 年前

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

    在您的位置和员工模型上,添加以下关系:

    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   |
                         ...
    

    使用此设置,您可以制作任何所需的模型 phonable 只需添加 morphOne() morphMany() 与它的关系。

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

    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) .