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 管理员更新用户信息,更新自己的管理员帐户信息时重复的电子邮件条目的主要内容,如果未能解决你的问题,请参考以下文章

Zimbra 管理员如何更新用户邮箱中保存的联系人信息?

如何更新 Laravel 集体中的唯一字段? [复制]

Laravel / 数据库 - 安全

Laravel 5 更新验证电子邮件需要是唯一的

在Laravel中,当我直接用数据库更新内容时,我怎样才能保持搜索索引有正确的数据更新?

基于java的博士生信息管理系统