Laravel 验证更新和保存的差异

Posted

技术标签:

【中文标题】Laravel 验证更新和保存的差异【英文标题】:Laravel validation differences on update and save 【发布时间】:2015-01-02 19:11:19 【问题描述】:

我正在使用 Jeffrey Way 的模型验证 (https://github.com/JeffreyWay/Laravel-Model-Validation) 来验证保存和更新。使用此方法,假设您在条目上填写更新某些字段,然后调用save() 方法,验证将在条目上当前设置的所有字段上运行。但是,如果验证需要一个字段(例如电子邮件地址)是唯一的,则验证将失败,因为它已经存在:

用户.php

protected static $rules = [
    'email' => 'required|email|unique:users',
    'firstname' => 'required',
    'lastname' => 'required'
];

Controller.php:

     // Get user from id
    $user = User::find($id);

    // Update user
    $user->update($data);

    // Validation when model is saved, via Way\Database\Model
    if ($user->save())
    
            return Response::json([
                'data' => $user->toArray()
            ], 200);
    

    if ($user->hasErrors())
    
        return Response::json([
            'errors' => $user->getErrors()
        ]);
    

将返回错误,因为电子邮件地址未通过验证。那么,使用这种方法,您如何告诉验证器忽略电子邮件的唯一规则?

【问题讨论】:

【参考方案1】:

我遇到过这个问题!我自己决定了这个问题。

protected static $rules = [
    'email' => $user->email == Input::get('email') ? 'required|email' : 'required|email|unique:users',
    'firstname' => 'required',
    'lastname' => 'required'
];

【讨论】:

【参考方案2】:

你不能使用这个包来做到这一点,因为你需要为unique 规则传递 id。你可以这样做:

protected static $rules = [
    'email' => 'required|email|unique:users,email,id',
    'firstname' => 'required',
    'lastname' => 'required'
];

并扩展此模型以添加您的自定义验证方法以将 id 替换为 id 属性

【讨论】:

【参考方案3】:

我想我用不同的方法使用类似的行为。使用此模型,我认为您应该重写 validate 方法以从自定义方法中获取规则,这样您就可以为现有模型设置新规则。

这样的事情可能会奏效:

protected function processRules($rules = array()) 
     $result = [];
     if (empty($rules)) 
         $rules = static::$rules; 
     
     // Add unique except :id
     $replace = ($this->exists()) ? ',' . $this->getKey() : '';
     foreach ($rules as $key => $rule) 
         $result[$key] = str_replace(',:' . $this->getKeyName(), $replace, $rule);
     

     return $result;       


并覆盖您的验证方法以调用proccessRules 方法。

 public function validate() 
     $v = $this->validator->make($this->attributes, $this->processRules(static::$rules), static::$messages);
     if ($v->passes()) 
         return true;
     
     $this->setErrors($v->messages());
     return false;
 

现在,您可以将email 规则定义为required|email|unique:users:id,当它是新用户时,规则应为required|email|unique:users,而当您更新ID 为1234 的用户时,规则将为required|email|unique:users:1234

我希望它对你有用。

【讨论】:

这是完美的 - 工作正常。但是,在(empty($rules) 之后,您的代码中缺少一个“)”。感谢您的帮助! 不客气。它几乎与我目前使用的模型相同——还有一些其他的添加——所以我已经解决了这个问题。也许您可能对 Ardent (github.com/laravelbook/ardent) 感兴趣,我正在使用这个。我修正了括号;-)

以上是关于Laravel 验证更新和保存的差异的主要内容,如果未能解决你的问题,请参考以下文章

使用“logoutOtherDevices”时,Laravel 新密码不会保存到数据库中

Laravel:更新和创建时验证唯一

Laravel 更新密码通过验证但不更新记录

Laravel 在商店和更新上的表单请求验证使用相同的验证

Laravel 5.4 验证请求,如何处理更新时的唯一验证?

如何在 laravel 中更新时验证电子邮件