Laravel 管理员更新用户信息,更新自己的管理员帐户信息时重复的电子邮件条目
Posted
技术标签:
【中文标题】Laravel 管理员更新用户信息,更新自己的管理员帐户信息时重复的电子邮件条目【英文标题】:Laravel admin update users' info, duplicate email entry when updating his own admin account information 【发布时间】:2021-12-05 11:42:45 【问题描述】:我正在开发一个 laravel 8 应用程序,并使用 spatie/laravel-permission 获取角色和权限。在管理页面上,我显示了管理员可以对其进行 CRUD 操作的所有用户。用户列表还包括他自己的管理员帐户。
我遇到的问题是更新用户详细信息时。管理员可以通过验证成功更新其他用户的用户帐户信息。但是,如果管理员尝试编辑他自己的管理员帐户的信息,则验证通过但我收到 SQL 错误:
违反完整性约束:1062 Duplicate entry 'admin@email.com' 对于键“users_email_unique”
请参阅下面我的UserController
update
方法,用于通过验证更新用户信息:
public function update(Request $request, User $user)
$edit_user_rules = array(
// ... other validation rules ...
//'email' => "required|email|unique:users,email,$user->id", //. auth()->user()->id,
'email' => ['required', 'string', 'email', Rule::unique('users')->ignore($user->id)],
// ... other validation rules ...
);
$validator = Validator::make($request->all(), $edit_user_rules);
if ($validator->fails())
Session::flash('failed', 'Failed to save User details!');
return redirect(route('editUser', ['user' => $user->id]))->withErrors($validator)->withInput();
else
$validated = $validator->validated();
$updatedUser = User::find($user)->first();
// ... other user fields ...
$updatedUser->username = $validated['username'];
$updatedUser->email = $validated['email'];
// ... other user fields ...
if ($updatedUser->save())
return redirect(route('allUsers'));
else
return redirect(route('allUsers')); // with errors
例如,我尝试在email
字段上使用不同的验证规则,
"required|email|unique:users,email,$user->id"
"required|email|unique:users,email," . auth()->user()->id
但没有一个有效。所以我使用验证Rule
来验证唯一的电子邮件字段。当我尝试更新其他用户的信息时它工作正常,但在更新管理员自己的帐户时收到 SQL 重复电子邮件错误。
如果我能得到任何帮助,我将不胜感激
【问题讨论】:
【参考方案1】:错误正在通过验证规则,但在保存规则时失败。这是因为您没有正确获取用户。 find()
自动获取第一条记录,因此 first()
是不需要的,实际上可能是拉错了帐户。当我在本地尝试 User::find(3)->first()
时,我得到的是用户 1 而不是用户 3。请从您的通话中删除 first()
。
$updatedUser = User::find($user->id);
【讨论】:
我不得不将其更改为User::find($user->id)
,它运行良好,谢谢! find($user)
实际上返回了超过 1 个用户的集合。使用first()
确实返回了错误的用户位-超出范围,但为什么会发生这种情况?我以为它只是返回集合中的第一个对象
通常是这样,但正如您所提到的,User::find($user)
返回了一个集合而不是单个用户,因此first()
返回了该集合的第一个。
虽然实际上这条线是完全没有必要的。您已经拥有来自public function update(Request $request, User $user)
的用户,因此您只需修改该$user
而无需重新获取它。
是有道理的,但这引发了一个问题,即为什么我使用find($user)
获取集合,但使用find($user->id)
获取1 个正确的用户记录。 Laravel 的 type 提示参数不是默认按 ID 搜索的吗?
显然不是。我刚刚用对象记录了 find 的 sql 请求,它传入了每个属性值,将其更改为 IN
请求。所以 User::find($user)
看起来像 select * from `users` where `users`.`id` in (3, 'myemail@email', 'My name', 1, ...)
考虑到我的用户表中有一些布尔标志,它拉出了 2 个用户:1 和 3。【参考方案2】:
您没有确定哪一列应该是唯一的以忽略他自己。
将您的电子邮件验证行更改为:
'email' => ['required', 'email', Rule::unique('users', 'email')->ignore($user->id)],
别忘了把这个赞放在你的代码顶部 use Illuminate\Validation\Rule;
。
【讨论】:
希望能帮到您。 尝试改变它,但仍然得到同样的错误以上是关于Laravel 管理员更新用户信息,更新自己的管理员帐户信息时重复的电子邮件条目的主要内容,如果未能解决你的问题,请参考以下文章