1
votes

I'm using Jeffrey Way's model validation (https://github.com/JeffreyWay/Laravel-Model-Validation) to validate both on save and update. With this method, let's say you fill a update some fields on an entry, then call the save() method, the validation will run on all the fields currently set on the entry. But if the validation requires a field, say the email address, to be unique, the validation will fail because it already exists:

User.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()
        ]);
    }

Will return errors because the email address failed the validation. So, with this method, how do you tell the validator to ignore the unique rule for the email?

3

3 Answers

0
votes

I think I use similar behaviour with different approach. Using this model, I thing you shold override the validate method to get the rules from a custom method, in witch you could set your new rules for existing models.

Something like this could work:

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;       

}

And override your validate method to call the proccessRules method.

 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;
 }

So now, you can define your email rule as required|email|unique:users:id, and when its a new User the rule should be required|email|unique:users and when you update the User with id 1234 the rule will be required|email|unique:users:1234.

I hope it works fine for you.

0
votes

I've had this problem! I decided the problem on their own.

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

You cannot do it using this package, because you need to pass id for the unique rule. You could do it this way:

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

and extend this model to add your custom validation method to replace {id} with id attribute