Laravel更新模型,具有属性的唯一验证规则

Tom*_*ald 61 php validation laravel eloquent

我有一个laravel User模型,它具有唯一的验证规则usernameemail.在我的存储库中,当我更新模型时,我重新验证字段,以便不会出现所需规则验证的问题:

public function update($id, $data) {
    $user = $this->findById($id);
    $user->fill($data);
    $this->validate($user->toArray());
    $user->save();
    return $user;
}
Run Code Online (Sandbox Code Playgroud)

这在测试中失败了

ValidationException: {"username":["The username has already been taken."],"email":["The email has already been taken."]}
Run Code Online (Sandbox Code Playgroud)

有没有办法优雅地解决这个问题?

mar*_*nuy 122

id当前正在更新的实例附加到验证器.

  1. 传递id您的实例以忽略唯一验证器.

  2. 在验证程序中,使用参数检测您是要更新还是创建资源.

如果更新,强制唯一规则忽略给定的id:

//rules
'email' => 'unique:users,email_address,' . $userId,
Run Code Online (Sandbox Code Playgroud)

如果正在创建,请照常进行:

//rules
'email' => 'unique:users,email_address',
Run Code Online (Sandbox Code Playgroud)

  • @ xcy7e웃:https://laravel.com/docs/5.3/validation`唯一:表,列,除了,idColumn` (3认同)
  • 按预期工作 (2认同)

BaM*_*BaM 29

另一种优雅方式......

在您的模型中,创建一个静态函数:

public static function rules ($id=0, $merge=[]) {
    return array_merge(
        [
            'username'  => 'required|min:3|max:12|unique:users,username' . ($id ? ",$id" : ''),
            'email'     => 'required|email|unique:member'. ($id ? ",id,$id" : ''),
            'firstname' => 'required|min:2',
            'lastname'  => 'required|min:2',
            ...
        ], 
        $merge);
}
Run Code Online (Sandbox Code Playgroud)

创建验证:

$validator = Validator::make($input, User::rules());
Run Code Online (Sandbox Code Playgroud)

更新验证:

$validator = Validator::make($input, User::rules($id));
Run Code Online (Sandbox Code Playgroud)

有关更新的验证,以及一些其他规则:

$extend_rules = [
    'password'       => 'required|min:6|same:password_again',
    'password_again' => 'required'
];
$validator = Validator::make($input, User::rules($id, $extend_rules));
Run Code Online (Sandbox Code Playgroud)

尼斯.

  • 很不错!为了让我的以这种方式工作,我需要以下内容:`'email' => 'required|email|unique:member'。($id ? ",id,$id" : '')` (2认同)

小智 10

Laravel 中不同列 ID 的唯一验证

'UserEmail'=>"required|email|unique:users,UserEmail,$userID,UserID"
Run Code Online (Sandbox Code Playgroud)


Tom*_*ald 8

在我的问题中工作:

public function update($id, $data) {
    $user = $this->findById($id);
    $user->fill($data);
    $this->validate($user->toArray(), $id);
    $user->save();
    return $user;
}


public function validate($data, $id=null) {
    $rules = User::$rules;
    if ($id !== null) {
        $rules['username'] .= ",$id";
        $rules['email'] .= ",$id";
    }
    $validation = Validator::make($data, $rules);
    if ($validation->fails()) {
        throw new ValidationException($validation);
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

是我所做的,基于上面接受的答案.

编辑:使用表单请求,一切都变得更简单:

<?php namespace App\Http\Requests;

class UpdateUserRequest extends Request
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => 'required|unique:users,username,'.$this->id,
            'email' => 'required|unique:users,email,'.$this->id,
        ];
    }
}
Run Code Online (Sandbox Code Playgroud)

您只需要将UpdateUserRequest传递给更新方法,并确保POST模型ID.

  • 您在哪里发布ID? (2认同)

DaS*_*Sid 5

或者你可以在你的表单请求中做的是(对于 Laravel 5.3+)

public function rules()
    {
        return [

            'email' => 'required|email|unique:users,email,'.$this->user, //here user is users/{user} from resource's route url
               ];
    }
Run Code Online (Sandbox Code Playgroud)

我已经在 Laravel 5.6 中完成了它并且它有效。