多对多
让我们说有角色和权限。每个角色可能属于许多权限,每个权限可能属于许多角色。所以会有 3 张桌子。两个型号和一个数据透视表。一个 roles
,users
和 permission_role
表。
榜样
public function permissions()
{
return $this->belongsToMany(Permission::class);
}
许可模式
public function roles()
{
return $this->belongsToMany(Roles::class);
}
注意:1
在为数据透视表使用不同的表名时考虑遵循。
假设你想使用 role_permission
而不是 permission_role
,因为雄辩使用字母顺序来构建数据透视表名称。你需要将数据透视表名称作为第二个参数传递,如下所示。
榜样
public function permissions()
{
return $this->belongsToMany(Permission::class, 'role_permission');
}
许可模式
public function roles()
{
return $this->belongsToMany(Roles::class, 'role_permission');
}
笔记 2
在数据透视表中使用不同的键名时考虑跟随。
Eloquent 假设如果没有键作为第三和第四个参数传递,那么它将是带有 _id
的单个表名。因此它假设枢轴将具有 role_id
和 permission_id
字段。如果要使用除这些之外的其他键,则应将其作为第三个和第四个参数传递。
让我们说如果使用 other_role_id
而不是 role_id
和 other_permission_id
而不是 permission_id
。所以它将如下。
榜样
public function permissions()
{
return $this->belongsToMany(Permission::class, 'role_permission', 'other_role_id', 'other_permission_id');
}
许可模式
public function roles()
{
return $this->belongsToMany(Roles::class, 'role_permission', 'other_permission_id', 'other_role_id');
}
使用 withPivot()
访问中间表
假设你在数据透视表中有第三列’ permission_assigned_date ‘。默认情况下,只有模型键才会出现在数据透视表对象上。现在要在查询结果中获取此列,你需要在 withPivot()
函数中添加该名称。
public function permissions()
{
return $this->belongsToMany(Permission::class, 'role_permission', 'other_role_id', 'other_permission_id')->withPivot('permission_assigned_date');
}
附加/分离
Eloquent 还提供了一些额外的辅助方法,使相关模型的使用更加方便。例如,假设用户可以拥有多个角色,而角色可以拥有许多权限。要通过在连接模型的中间表中插入记录来将角色附加到权限,请使用 attach 方法:
$role= App\Role::find(1);
$role->permissions()->attach($permissionId);
将关系附加到模型时,你还可以传递要插入到中间表中的其他数据数组:
$rol->roles()->attach($permissionId, ['permission_assigned_date' => $date]);
同样,要删除针对角色的特定权限,请使用 detach 功能
$role= App\Role::find(1);
//will remove permission 1,2,3 against role 1
$role->permissions()->detach([1, 2, 3]);
同步关联
你还可以使用 sync 方法构建多对多关联。sync 方法接受要放在中间表上的 ID 数组。将从中间表中删除任何不在给定数组中的 ID。因此,在此操作完成后,只有给定数组中的 ID 将存在于中间表中:
//will keep permission id's 1,2,3 against Role id 1
$role= App\Role::find(1)
$role->permissions()->sync([1, 2, 3]);