Laravel 雄辩的多对多模型
Posted
技术标签:
【中文标题】Laravel 雄辩的多对多模型【英文标题】:Laravel eloquent many to many to many model 【发布时间】:2014-03-17 14:28:51 【问题描述】:我在 laravel 4 中做一个项目,我已经停下来了。
任务表:
task_id (PK)
task_title
测量表:
measure_id (PK)
measure_title
例程表:
routine_id (PK)
date
time
value
emp_id (FK)
emps 表:
emp_id (PK)
first_name
last_name
user_name
email
user_type
现在我很困惑的是如何用雄辩的方式模拟这些关系,因为我似乎无法弄清楚。在phpmyadmin
DB 中,我目前有两个表将任务和测量值连接到具有task_routine
的例程:task_id (PK)
、routine_id (PK)
和measure_routine
:measure_id (PK)
、routine_id(PK)
。
希望在我写这篇文章的时候,我脑海中的声音就这么清晰,感谢您的帮助!
【问题讨论】:
你的问题到底是什么?您希望如何在哪些表之间建立关系? 是的 - 您只是在寻找设置方法,还是寻找将任务直接连接到度量的方法? 查看本教程...vegibit.com/many-to-many-relationships-in-laravel 【参考方案1】:首先在所有表格中将PK
字段从*_id
更改为id
。如果您想为一个表与另一个表建立关系,那么约定是,您应该使用父表的name_id
(名称应为单数形式)在子表中保留一个外键,例如,构建emps
和 routines
表之间的关系,您应该在 routines
表中使用 emp_id
外键,并且您的 emps
表应该包含 id
PK
。因此,您的 emps
表是父表,routines
是 emps
的子表,两个表中的记录应该是这样的(可以使用自定义约定):
表emps
(父):
id (pk) | first_name | more fields ...
1 | Mr | ...
2 | Miss | ...
3 | Mrs | ...
表routines
(子):
id (pk) | emp_id (FK) | more fields ...
1 | 1 | ... - Child of emps table's first record
2 | 3 | ... - Child of emps table's third record
3 | 3 | ... - Child of emps table's third record
这里,emps
表中的每个id
都用作emp_id
字段中routines
表中的外键。所以,emps
表在routines
表中有三个相关记录,emps
表中的第一条记录与routines
表中的第一条记录和emps
表中的第三条记录相关(id 为3
) 在routines
表中有两条相关记录(第二条和第三条),因为两条记录都包含emps
表在emp_id
字段中的第三条记录的id 3
。
现在使用 Laravel 建立关系:
如果您的父表在子表中只有一个相关表,则使用one-to-one
,例如,如果emps
表中id 为1
(第一条记录)的记录在routines
中只有一个相关记录使用emp_id
字段的表,其值为1
,如果它不能在routines
表中的多个记录中,则它是one-to-one
关系,在上面给出的示例记录中不是one-to-one
关系,因为在routines
表中,有两条记录与emps
表中的id/pk
相同,因此它转到one-to-many
关系,因此可以将其读取为emps
记录中有许多routines
。要建立one-to-many
关系,我们可以使用:
class Emp extends Eloquent
public function routines()
return $this->hasMany('Routine');
Routine
模型:
class Routine extends Eloquent
public function emp()
return $this->belongsTo('Emp');
在one-to-many
关系中,父表可能包含多个具有相同id
的子记录,但如果子表中的记录也有许多父记录,则它应该是many-to-many
关系。例如,如果我们想在例程表中建立这样的关系(不可能两次使用相同的主键):
id (pk) | emp_id (FK) | more fields ...
1 | 1 | ...
2 | 2 | ... - Record 2(id) has parent 2(emp_id)
2 | 3 | ... - Record 2(id) has also parent 3(emp_id)
在这种情况下,这是一个many-to-many
关系,不可能在一个表中使用相同的id/PK
两次,因此我们需要使用第三个表在emps
表和routines
表之间建立many-to-many
关系表(称为pivot
表)来维护many-to-many
关系。所以,它看起来像下表:
表名应该是emp_routine
,但还有其他方法可以使用
不同的名称,但遵循此约定。
emp_routine
数据透视表:
id (pk) | emp_id (id/PK of emps) | routine_id (id/PK of routines) | more fields ...
1 | 1 | 1 | ...
2 | 2 | 1 | ...
3 | 1 | 2 | ...
这里,父母和孩子在两个表中都有多个相关记录,并且这个pivot
表维护了这种关系。
要使用Laravel
建立关系,我们可以使用:
class Emp extends Eloquent
public function routines()
return $this->belongsToMany('Routine');
Routine
模型:
class Routine extends Eloquent
public function emp()
return $this->belongsToMany('Emp');
在这种情况下,我们不需要 routines
表中的外键字段 (emp_id),因为我们使用数据透视表来维护关系,但如果它存在,则不会有问题。
应该注意的是,每当您在父表中插入/更新任何记录时,您还必须在数据透视表中插入/更新关系数据,Laravel 为这些提供了有用的方法,所以check the manual (relationship)。
【讨论】:
嘿,感谢您的冗长回答,它对我理解它的工作原理有很大帮助。如果您示例中的 emp 表与两个表具有多对多关系,这将如何工作?只需为所有三个表扩展 Eloquent 并在两个表上对 emp 运行 belongsToMany 函数,然后对两个表运行emp? 是的,对于many-to-many
关系,请使用每个模型中的belongsToMany
并使用pivot
表。
感谢所有帮助,非常感谢!以上是关于Laravel 雄辩的多对多模型的主要内容,如果未能解决你的问题,请参考以下文章