多对多关系同步将删除所有选定的选项



我有一个多对多关系中的角色和权限表,以及透视表permission_role。尝试更新角色的权限时遇到此问题。

例如:在创建管理员角色时:我向其添加了权限view_users。现在,在尝试更新它时,给它额外的权限create_team

代码:

$roleUpdate = Role::where('id', $role->id)->update([
'name' => $request->input('name'),
'updated_at' => Carbon::now()
]);
$permissions = $request->input('permission');
//dd($permissions);
foreach ($permissions as $permission) {
$role->permissions()->sync($permission, true);
}
if ($roleUpdate) {
Alert::toast('Role updated successfully', 'success');
return redirect()
->route('roles.index', ['role' => $role->id])
->with('success', 'Role Updated Successfully');
}
//redirect
return back()->withInput();

当我在权限上dd()查看哪些选项通过时,我得到了预期的正确结果

array:2 [▼
0 => "3"
1 => "4"
]

但是,当数据保存到数据库中时,只存储新值,而删除旧值。我知道这个问题可能是由以下行将分离设置为true引起的:

$role->permissions()->sync($permission,true); 

但是,如果我将其设置为false,那么当我通过删除其中一个权限来更新角色的权限时,它就不起作用。它不会分离。根据下面链接的文档中给出的解释,它似乎不起作用。不确定我错过了什么Laravel Docs

问题是您使用的是foreach:

array:2 [▼
0 => "3"
1 => "4"
]
foreach ($permissions as $permission) {
$role->permissions()->sync($permission, true);
}

在第一个循环中,您从角色中删除除id为3的权限之外的所有权限,在第二个循环中再次从角色中移除除id为4的权限以外的所有权限。这意味着您已经删除了之前设置的id为3的权限。

移除foreach并传递整个数组应该可以:

// no need to pass 'true' as the second argument as it is the default value
$role->permissions()->sync($request->input('permission'));

来自文档:

您也可以使用sync方法来构造多对多协会。sync方法接受要放置在中间表格。任何不在给定数组中的ID都将已从中间表中删除。所以,在这个操作之后完成,则只有给定数组中的ID将存在于中间表格:

$user->roles()->sync([1, 2, 3]);

最新更新