Laravel-Model-Validation
Laravel-Model-Validation copied to clipboard
Trying to understand how to 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?
There is a third field option on the unique validator that lets you specify an id to ignore in the validation check. So you can do something like:
$protected static $rules = array( 'email' => 'required|unique:users,email,{{$id}}');
Adding {{$id}}
to my ruleset doesn't seem to work. I've overridden the model to achieve this within a BaseModel
class.
/**
* Pre-process the rules by replacing instances of {{$id}} with the model id
*
* @return bool
*/
public function validate()
{
foreach(static::$rules as $field => $rules) {
$rules = explode('|', $rules);
foreach($rules as &$rule) {
$rule = explode(':', $rule);
if($rule[0] == 'unique') {
$rule[1] = str_replace('{{$id}}', $this->id, $rule[1]);
}
$rule = implode(':', $rule);
}
static::$rules[$field] = implode($rules, '|');
}
return parent::validate();
}
I think what @tomwalsh wanted to say was that you have to append the id
of the user to update. But to alter the rules you will have to copy the Laravel-Model-Validation Model file to your models folder and create a method to modify the static $rules
array.
// in Models/Model.php
static function setRules($key = '', $value = '')
{
if(array_key_exists($key, static::$rules))
static::$rules[$key] = $value;
return static::$rules;
}
Now in your update
method (in your controller file) you'll have to alter the $rules
array before it is used to validate the data:
// In Controllers/SomeController.php
public function update($accountId)
{
Account::setRules('email', 'email|required|unique:accounts,email,'.$accountId);
// Your logic here
}
That's it. You can now adapt your rules to any situation. I'll probably be pushing new changes to this repository sometime soon, I will include this proposal.
Also, check out Laravel Validation Docs (unique rule)