【问题标题】:Laravel admin update users' info, duplicate email entry when updating his own admin account informationLaravel 管理员更新用户信息,更新自己的管理员帐户信息时重复的电子邮件条目
【发布时间】: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 重复电子邮件错误。

如果我能得到任何帮助,我将不胜感激

【问题讨论】:

    标签: php laravel validation duplicates


    【解决方案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;

    【讨论】:

    • 希望能帮到您。
    • 尝试改变它,但仍然得到同样的错误
    猜你喜欢
    • 1970-01-01
    • 2019-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-05
    相关资源
    最近更新 更多