Laravel:多对多共享表 [英] Laravel: many-to-many with shared table
问题描述
我有一个Locations
模型,其中有很多Employees
-类似地Employees
属于To Locations
I have Locations
model which hasMany Employees
-- similarly Employees
belongsTo Locations
这很好,效果很好,但是后来我考虑添加PhoneNumbers
. Location
或Employee
都可以具有电话号码(办公室号码与个人号码)
This is nice and works well, but then I looked at adding PhoneNumbers
. Either a Location
or an Employee
could have a phone number (office numbers versus personal numbers)
逻辑上:
Locations
hasMany PhoneNumbers
(多条办公室线)
和
Employees
hasMany PhoneNumbers
(家庭/牢房?)
Locations
hasMany PhoneNumbers
(multiple office lines)
and
Employees
hasMany PhoneNumbers
(home / cell ?)
但是,当您在Laravel中创建hasMany关系时,会向PhoneNumbers
表中添加一个字段.因此,我们现在有两个字段:location_id
和employee_id
However when you create a hasMany relationship like this in Laravel it adds a field to the PhoneNumbers
table. 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:
+----+--------------+-------------+-------------+
| 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?)
如何使用同一个辅助表创建多个单独的多对多关系?
注意:在此示例中,我可以在每个单独的表(locations.phone_number
,employees.phone_number
等)上创建一个phone_number
字段,但是出于两个原因,我希望避免这种情况:
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:
- 数据完整性(如果所有电话号码都在一个公用表中,则很容易确认未输入重复的电话号码)
- 绑定到更复杂的模型(用
Image
替换PhoneNumber
,现在您有更多的数据要处理)
- Data integrity (if all phone numbers are in one common table it's easy to verify duplicate phone numbers are not entered)
- Binding to more complex models (replace
PhoneNumber
withImage
and now you have a lot more data to deal with)
推荐答案
您正在寻找Laravel的多态关系.您不必为每个相关表创建一个新字段,而要拥有两个字段:相关ID和相关类型.
You're looking for Laravel's polymorphic relationship. Instead of creating a new field for each related table, you have two fields: related id and related type.
在位置"和员工"模型上,添加以下关系:
On both your Location and Employee model, add the following relationship:
public function phones()
{
return $this->morphMany('PhoneNumber', 'phonable');
}
在您的PhoneNumber型号上,添加以下关系:
On your PhoneNumber model, add the following relationship:
public function phonable()
{
return $this->morphTo();
}
在phone_numbers表上,添加两个新字段:phonable_type和phonable_id.在迁移中,这些字段是使用morphs()
方法添加的:$table->morphs('phonable');
On your phone_numbers table, add two new fields: phonable_type and phonable_id. In a migration, these fields are added with the morphs()
method: $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 |
...
通过此设置,只需向其添加morphOne()
或morphMany()
关系即可创建所需的任何模型.
With this setup, you can make any model you want phonable
just by adding a morphOne()
or morphMany()
relationship to it.
此外,关系属性将生成与类型相关的正确模型.鉴于以上数据:
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
这篇关于Laravel:多对多共享表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!