6

我使用以下规则来验证创建新用户:

protected $rules= [
    'name'    => 'required',
    'email'    => [
        'required',
        'unique:user',
        'email'
    ]
];

更新现有用户时,我使用如上所示的相同规则集,但如果用户根本没有更改他的电子邮件,则不希望出现验证错误。

我目前使用以下方法解决此问题:

if (!User::changed('email')) {
    unset($user->email);
}

对我来说,这感觉像是一个肮脏的解决方法,所以我想知道是否有更好的选择。

另请注意,该changed方法是我自己编写的。有谁知道是否有本地 Laravel 4 方法来检查模型属性是否已更改?

谢谢!

4

6 回答 6

9

唯一验证规则允许忽略给定的 ID,在您的情况下,它是您正在更新的数据集的 ID。

'email' => 'unique:users,email_address,10'

http://four.laravel.com/docs/validation#rule-unique

于 2013-05-13T09:00:27.513 回答
4

一种方法是在模型中创建一个验证函数,并在控制器传入输入、场景和 id(忽略)的情况下调用它。

public function validate($input, $scenario, $id = null)
{
    $rules = [];

    switch($scenario)
    {
        case 'store':
            $rules   = [
                'name'     => 'required|min:5|unique:users',
                'email'    => 'required|email|unique:users',
                'password' => 'required|min:4|confirmed'
            ];
            break;

        case 'update';
            $rules   = [
                'name'     => 'required|min:5|unique:users' .',name,' . $id,
                'email'    => 'required|email|unique:users' .',email,' . $id,
                'password' => 'min:4|confirmed'
            ];
            break;
    }

    return Validator::make($input, $rules);
}

然后在控制器中:

    $input      = Input::all();
    $validation = $user->validate($input, 'update', $user->id);

    if ($validation->fails())
    {
        // Do stuff
    }
    else
    {
        // Validation passes
        // Do other stuff
    }

正如其他人提到的,唯一规则的第三个参数指定要忽略的 id。您可以添加其他情况,例如“登录”以重用验证功能。

另外,Tuts Premium 的 Jeffrey Way 在“Laravel 4 中的新功能”中有一系列精彩的课程,其中包括使用服务和侦听器处理验证的其他几种方法。

于 2013-08-06T05:01:48.447 回答
1

截至 2014-01-14,您可以使用sometimes属性,我相信泰勒在 2 天前将它们添加到 Laravel 4.1

$v = Validator::make($data, array(
    'email' => 'sometimes|required|email',
));

sometimes仅在存在时验证输入。如果您没有插入的默认值,这可能适合也可能不适合您的确切情况。

http://laravel.com/docs/validation#conditionally-adding-rules

于 2014-01-14T12:02:54.723 回答
1

请参阅http://four.laravel.com/docs/validation#rule-unique上的文档

您可以排除用户自己的 id

protected $rules= [
    'name'    => 'required',
    'email'    => [
        'required',
        'unique:user,email,THE_USERS_USER_ID',
        'email'
    ]
];
于 2013-05-13T09:00:46.177 回答
0

我在验证器函数中处理这种事情。我的验证器数组设置为类变量。然后我做这样的事情:

public function validate() 
{
    //exclude the current user id from 'unqiue' validators
    if( $this->id > 0 )
    {
        $usernameUnique = 'unique:users,username,'.$this->id;
        $emailUnique = 'unique:users,email,'.$this->id;
        $apiUnique = 'unique:users,api_key,'.$this->id;
    }
    else
    {
        $usernameUnique = 'unique:users,username';
        $emailUnique = 'unique:users,email';
        $apiUnique = 'unique:users,api_key';
    }

    $this->validators['username'] = array('required', 'max:32', $usernameUnique);
    $this->validators['email'] = array('required', 'max:32', $emailUnique);
    $this->validators['api_key'] = array('required', 'max:32', $apiUnique);

    $val = Validator::make($this->attributes, $this->validators);

    if ($val->fails())
    {
        throw new ValidationException($val);
    }
}
于 2013-07-09T18:52:12.293 回答
0

我通过对需要这样做的模型(如用户)设置不同的更新和创建规则来解决这个问题。

我有一个扩展 Eloquent 的模型类,我在其中定义验证,然后扩展模型的所有子模型都可以定义$rules$update_rules。如果您只定义 $rules,它将用于创建和更新。

class Model extends Eloquent {
    protected $errors;
    protected static $rules = array();    
    protected $validator;

    public function __construct(array $attributes = array(), Validator $validator = null) {
        parent::__construct($attributes);    
        $this->validator = $validator ?: \App::make('validator');
    }

    protected static function boot() {
        parent::boot();

        # call validatie when createing
        static::creating(function($model) {
            return $model->validate();
        });

        # call validatie when updating with $is_update = true param
        static::updating(function($model) {
            return $model->validate(true);
        });
    }

    public function validate($is_update = false) {
        # if we have $update_rules defined in the child model, and save is an update
        if ($is_update and isset(static::$update_rules)) {
            $v = $this->validator->make($this->attributes, static::$update_rules);
        }
        else {
            $v = $this->validator->make($this->attributes, static::$rules);
        }

        if ($v->passes()) {
            return true;
        }

        $this->setErrors($v->messages());
        return false;
    }

    protected function setErrors($errors) {
        $this->errors = $errors;
    }

    public function getErrors() {
        return $this->errors;
    }

    public function hasErrors() {
        return ! empty($this->errors);
    }
}
于 2014-04-01T23:57:23.303 回答