在获得Laravel: many-to-many with shared table的帮助之后,我想创建一个“人物”表格 - Employee
是 Person
,但是Customer
1}} 是 Person
而Supplier
是 Person
但是Person
可以 Employee
和 a Customer
(为什么不呢?)
为了解决这个问题,我决定:
Person
有多个Role
Role
属于Person
Role
变身来personable
Employee
morphsOne personable
因此,Employee
仅指向一个Person
(通过Role
),但Person
可能有多个Roles
(Employee
, Customer
等)
逻辑上这个设置是有意义的,但我无法弄清楚我需要添加,更改或做什么才能真正使用这个模型。经过一些实验,我找到了一种写作方法,虽然我更喜欢更优雅的解决方案:
// Create a new Person and link it to an Employee
$person = new Person(['name' => 'Steven']);
$employee = new Employee(['employee_id' => 1234]);
// Incorrect: person() is a Role, not a Person
$employee->person()->save($person);
// Incorrect: person() is *actually* a Builder and has no method person()
$employee->person()->person()->save($person);
// Throws no errors and seems to work, but it's not very elegant
$role = new Role();
$person->roles()->save($role);
$employee->person()->save($role);
// Desired:
$employee->person()->save($person);
// Also acceptable:
$employee->person = $person;
$employee->is( $person );
然而我找不到从这个模型中读取的好方法:
// Grab a person
$person = Person::where('name', '=', 'Steven');
// Attempt to find the employee for this person
$employee = $person->roles->.... Employee?
$employee = Employee::where(.... Person =? Role =?
foreach( $person->roles as $role ) { if( $role... is an Employee?
$employee = Employee::whereHas('person', function($q){ $q->where(... person is $person?
阅读Laravel文档,他们有很好的示例和文档:
在非多态的情况下,只需转动它就可以简化关系。而不是Role
拥有Person
(多对一),而是Person
有一个Role
(一对多)
然而,在多态的情况下,没有“多对一”。乍一看,它可以使用多态多对多和应用程序逻辑进行模拟,以维护“一个员工只能有一个人”的约束。无论如何阅读文档,多态多对多关系都要求变形表知道它可以变形的类型:
class Person extends Model {
public function employees()
{
return $this->morphedByMany('App\Employee', 'personable');
}
public function customers()
{
return $this->morphedByMany('App\Customer', 'personable');
}
}
当我为Person
创建新角色时,这不能很好地扩展。