[英]Laravel: many-to-many with shared table
I have Locations
model which hasMany Employees
-- similarly Employees
belongsTo Locations
我有一个具有许多
Employees
Locations
模型-类似地, Employees
属于Locations
This is nice and works well, but then I looked at adding PhoneNumbers
. 很好,效果很好,但是后来我看了添加
PhoneNumbers
。 Either a Location
or an Employee
could have a phone number (office numbers versus personal numbers) 无论是
Location
或Employee
可能有一个电话号码(办公室号码与个人号码)
Logically: 从逻辑上讲:
Locations
hasMany PhoneNumbers
(multiple office lines) and Employees
hasMany PhoneNumbers
(home / cell ?) Locations
的hasMany PhoneNumbers
(多个办公室线)和Employees
的hasMany PhoneNumbers
(家庭/细胞?)
However when you create a hasMany relationship like this in Laravel it adds a field to the PhoneNumbers
table. 但是,当您在Laravel中创建hasMany关系时,会向
PhoneNumbers
表中添加一个字段。 So we now have two fields: location_id
and employee_id
因此,我们现在有两个字段:
location_id
和employee_id
I can get this to work if I make location_id
and employee_id
nullable, like so: 如果我将
location_id
和employee_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 |
...
However this doesn't scale very well if I add new entities that can possess phone numbers (customers? job applicants? suppliers?) 但是,如果我添加可以拥有电话号码的新实体(客户,求职者或供应商?),这将不能很好地扩展。
How can I create multiple separate many-to-many relationships with the same secondary table? 如何使用同一个辅助表创建多个单独的多对多关系?
Note: In this example I could just create a phone_number
field on each individual tables ( locations.phone_number
, employees.phone_number
, etc) however I wish to avoid this for two reasons: 注意:在此示例中,我只可以在每个表上创建一个
phone_number
字段( locations.phone_number
, employees.phone_number
等),但是出于两个原因,我希望避免这种情况:
PhoneNumber
with Image
and now you have a lot more data to deal with) Image
替换PhoneNumber
,现在您有更多数据要处理) You're looking for Laravel's polymorphic relationship. 您正在寻找Laravel的多态关系。 Instead of creating a new field for each related table, you have two fields: related id and related type.
您有两个字段,而不是为每个相关表创建一个新字段:相关ID和相关类型。
On both your Location and Employee model, add the following relationship: 在“位置”和“员工”模型上,添加以下关系:
public function phones()
{
return $this->morphMany('PhoneNumber', 'phonable');
}
On your PhoneNumber model, add the following relationship: 在您的PhoneNumber模型上,添加以下关系:
public function phonable()
{
return $this->morphTo();
}
On your phone_numbers table, add two new fields: phonable_type and phonable_id. 在phone_numbers表上,添加两个新字段:phonable_type和phonable_id。 In a migration, these fields are added with the
morphs()
method: $table->morphs('phonable');
在迁移中,这些字段使用
$table->morphs('phonable');
morphs()
方法添加: $table->morphs('phonable');
Once everything is setup, your data would look like this: 一切设置完成后,您的数据将如下所示:
+----+--------------+-------------+---------------+
| 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 |
...
With this setup, you can make any model you want phonable
just by adding a morphOne()
or morphMany()
relationship to it. 通过此设置,只需
phonable
添加morphOne()
或morphMany()
关系,就可以使任何模型成为可phonable
模型。
Additionally, the relationship attributes will generate the correct model related to the type. 此外,关系属性将生成与类型相关的正确模型。 Given the data above:
鉴于以上数据:
var_dump(PhoneNumber::find(1)->phonable); // will dump Location object
var_dump(PhoneNumber::find(4)->phonable); // will dump Employee object
The documentation on polymorphic relationships can be found here (4.2) or here (5.0) . 有关多态关系的文档可在此处(4.2)或此处(5.0)找到 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.