validating
validating copied to clipboard
Validation incorrect work with accessors
I have model with accessors, originaly I have integers in validated model properties, but when i accessing it, model returns me words represents that integers. Validating trait validating accessors result except of native values. I think - problem is on line ValidatingTrait:139:
$attributes = $this->getModel()->getAttributes();
This is by design, at some point the decision was made that the validator should operate on the mutated values. Looking back I'm not sure if I still think that was the right move, but that's how it is for now. Could look into adding an option that lets you opt-in/out of mutated values.
Hi,
I have same problem with throw a validation on password field in User model. I have a mutator for that field. This mutator function apply bcrypt function to my custom password and convert it in a string valid. I too would like can modify the validation on a custom and specific list fields.
Thanks for you work.
I came to the same conclusion as @EugeneG9. The method should be:
public function getModelAttributes()
{
return $this->getModel()->attributesToArray();
}
The attributesToArray method already returns attributes that are mutated and converts Carbon dates to strings. Plus, it adds appended accessors, and applies type casting.
Accessors especially pair really nicely with this validator class. Here's an example of a complex, model-specific validator rule. This ensures that the passed percentage fields all add to 100%.
use Illuminate\Database\Eloquent\Model;
use Watson\Validating\ValidatingTrait;
class SomeModel extends Model
{
use ValidatingTrait;
protected $fillable = [
'percent1',
'percent2',
'percent3',
];
// We validate the 'total' accessor even though it's not a fillable field
protected $rules = [
'percent1' => 'required|integer|between:0,100',
'percent2' => 'required|integer|between:0,100',
'percent3' => 'required|integer|between:0,100',
// the percent fields must add to 100%
'total' => 'required|integer|size:100',
];
public function getTotalAttribute()
{
return $this->percent1 + $this->percent2 + $this->percent3;
}
// The total attribute needs to be appended because it doesn't already exist
// Otherwise, Laravel's toArray method doesn't include it for efficiency
protected $appends = ['total'];
}
I can't think of another way to do this is other than with a separate validation in the controller before I would save the model. I prefer the model to handle validation of the data it represents. Also, I'd want that validation rule error to be grouped with any other failed rules.
I love that I can set the throwValidationExceptions flag and have the exception handler deal with error. It keeps everything sorted and clean.