Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel update model with unique validation rule for attribute

I have a Laravel User model which has a unique validation rule on username and email. In my Repository, when I update the model, I revalidate the fields, so as to not have a problem with required rule validation:

public function update($id, $data) {     $user = $this->findById($id);     $user->fill($data);     $this->validate($user->toArray());     $user->save();      return $user; } 

This fails in testing with:

ValidationException: {"username":["The username has already been taken."],"email":["The email has already been taken."]}

Is there a way of fixing this elegantly?

like image 944
Tom Macdonald Avatar asked Mar 14 '14 13:03

Tom Macdonald


People also ask

How to use unique validation in Laravel?

So you can use simple unique validation in laravel. The following unique validation rule is simple. And you can use it as follow: The following unique validation rules with column name on controller methods, you can use as follow: Before using unique validation with the rule, you need to import use Illuminate\Validation\Rule;.

What is the default email validation in Laravel?

The filter validator, which uses PHP's filter_var function, ships with Laravel and was Laravel's default email validation behavior prior to Laravel version 5.8. The dns and spoof validators require the PHP intl extension. ends_with: foo, bar ,...

What is the difference between authorize and rules in Laravel?

Each form request generated by Laravel has two methods: authorize and rules. As you might have guessed, the authorize method is responsible for determining if the currently authenticated user can perform the action represented by the request, while the rules method returns the validation rules that should apply to the request's data:

What is the current_password rule in Laravel 9?

The field under validation must be numeric. The field under validation must match the authenticated user's password. This rule was renamed to current_password with the intention of removing it in Laravel 9. Please use the Current Password rule instead.


2 Answers

Append the id of the instance currently being updated to the validator.

  1. Pass the id of your instance to ignore the unique validator.

  2. In the validator, use a parameter to detect if you are updating or creating the resource.

If updating, force the unique rule to ignore a given id:

//rules 'email' => 'unique:users,email_address,' . $userId, 

If creating, proceed as usual:

//rules 'email' => 'unique:users,email_address', 
like image 105
marcanuy Avatar answered Sep 22 '22 05:09

marcanuy


Another elegant way...

In your model, create a static function:

public static function rules ($id=0, $merge=[]) {     return array_merge(         [             'username'  => 'required|min:3|max:12|unique:users,username' . ($id ? ",$id" : ''),             'email'     => 'required|email|unique:member'. ($id ? ",id,$id" : ''),             'firstname' => 'required|min:2',             'lastname'  => 'required|min:2',             ...         ],          $merge); } 

Validation on create:

$validator = Validator::make($input, User::rules()); 

Validation on update:

$validator = Validator::make($input, User::rules($id)); 

Validation on update, with some additional rules:

$extend_rules = [     'password'       => 'required|min:6|same:password_again',     'password_again' => 'required' ]; $validator = Validator::make($input, User::rules($id, $extend_rules)); 

Nice.

like image 26
BaM Avatar answered Sep 24 '22 05:09

BaM