Laravel仅在更改后才请求更新唯一字段

时间:2018-07-17 10:22:18

标签: php laravel validation laravel-5 request

根据某些情况,我将无法验证用户的电子邮件地址。

例如

  

如果正在创建用户,则电子邮件地址必须唯一

     

如果用户正在更新,但电子邮件地址未更改,请忽略唯一的电子邮件规则

     

如果要更新用户且其电子邮件地址已更改,则该地址必须是唯一的

我环顾四周,我知道我可以根据类似方法指定不同的规则

public function rules()
{
    $user = User::find($this->users);

    switch($this->method())
    {
        case 'POST':
        {
            return [
                'user.email'      => 'required|email|unique:users,email',
            ];
        }
        case 'PUT':
        case 'PATCH':
        {
            return [
                'user.email'      => 'required|email,
            ];
        }
        default:break;
    }
}

是否有任何方法可以使它在put / patch情况下检查电子邮件地址是否已更改,如果必须更改,则该电子邮件地址必须是唯一的?

是否没有更清洁的方法来实现这一目标?也许没有开关盒?也许还有更多我尚未偶然发现的深度验证规则?

8 个答案:

答案 0 :(得分:4)

如果我对您的理解正确,那么如果电子邮件发生更改,您想添加unique验证,如果是这样,那么您只需要在验证中添加一个条件即可。如果您检查唯一的验证结构看起来像unique:table,column,except,idColumn,请检查documentation

因此验证将如下所示,当您创建新记录时$userId将为空,但在打补丁时它将具有价值。因此,此验证将同时适用于创建和修补程序。

$userId = isset($user) ? $user->id : null;

$rules = [
        'email' => 'required|email|unique:users,email,'. $userId.',id',
    ];

 $this->validate($request, $rules);

答案 1 :(得分:1)

有一个内置功能。您可以将实际用户ID添加到唯一约束(如果存在)中。这将确保唯一性约束仍然有效,但在值不变时不会失败:

$exists = $user->exists;
$rules = return [
    'user.email' => 'required|email|unique:users,email' . ($exists ? ','.$user->id : ''),
];

内部,这将执行以下查询:

SELECT count(id) FROM users WHERE email = 'some-mail@example.com' AND id != 42

仅当您将第三个参数添加到唯一验证规则时,后一部分AND id != 42才是查询的一部分。

答案 2 :(得分:0)

在控制器方法(存储和更新)中,您可以使用:

 $validations = [
        'email'                 => 'required|email|unique:users,email'
    ];

 $this->validate($request, $validations);

答案 3 :(得分:0)

在每个break;之后,您将丢失case.语句。对于Update(PATCH请求),您还必须在更新请求中传递id

public function rules()
{
    $user = User::find($this->users);

    switch($this->method())
    {
        case 'PATCH':
        {
            return [
                'user.email'      => 'required|email|unique:users,email,'. $user->id.',id',
            ];
        }
        break; // change here
        case 'PUT': break; // change here
        case 'POST':
        {
            return [
                'user.email'      => 'required|email,
            ];
        }
        break; // change here
        default:break;
    }
}

答案 4 :(得分:0)

$request->validate([
        'naam' => 'required|max:190|unique:database_name.table,column_where_you_check_unique,'.$id.',$id_column_reference'
    ]);

'naam'-表单输入字段名称

数据库名称(可选)-如果您有多个数据库

表(必填)-表名

column_where_you_check_unique(必填)-数据唯一的地方

$ id(必需)-使用id自动递增检查

$ id_column_reference-$ id的列名。

答案 5 :(得分:0)

我的方式:

'slug' => $site->slug !== $request->slug ? 'required|min:4|max:80|unique:sites' : 'required|min:4|max:80'

答案 6 :(得分:0)

您可以尝试

$exists = Section::where('code', $request->code)->exists();
        $isUpdateQuery = (($request->method() == 'PUT') || ($request->method() == 'PATCH'));
        $validatedData = $request->validate([
            "code" => ['required','unique:sections,code' . (($isUpdateQuery && $exists) ? ',' . $request->code . ',code': '')],
            "title" => 'required | json',
            "subtitle" => 'required | json',
            "btn_title" => 'required | json',
            "name" => 'required',
            "pageID" => 'required | exists:pages,pageID',
            "image" => 'nullable',
            "btn_link" => 'nullable',
        ]);

答案 7 :(得分:0)

我遇到了类似的问题,并在文档中找到了一种解决方法。

我的问题是,如果用户已经创建,电子邮件地址声称它不是唯一的,即使它已经注册给用户。

https://laravel.com/docs/8.x/validation#rule-unique

下面的几个标题是这样的:

use Illuminate\Validation\Rule;

$request->validate([
    'email' => [
        'required',
        Rule::unique('users')->ignore($user->id),
    ],
]);

执行以下操作:

<块引用>

验证电子邮件地址,使其成为必需且唯一,除非该行的用户 ID 与该用户匹配。