Laravel: Validation unique on update

Just a side note, most answers to this question talk about email_address while in Laravel's inbuilt auth system, the email field name is just email. Here is an example how you can validate a unique field, i.e. an email on the update:

In a Form Request, you do like this:

public function rules()
{
  return [
      'email' => 'required|email|unique:users,email,'.$this->user->id,
  ];
}

Or if you are validating your data in a controller directly:

public function update(Request $request, User $user)
{
  $request->validate([
      'email' => 'required|email|unique:users,email,'.$user->id,
  ]);
}

Update: If you are updating the signed in user and aren't injecting the User model into your route, you may encounter undefined property when accessing id on $this->user. In that case, use:

public function rules()
    {
      return [
          'email' => 'required|email|unique:users,email,'.$this->user()->id,
      ];
    }

A more elegant way since Laravel 5.7 is:

public function rules()
{
    return [
        'email' => ['required', 'email', \Illuminate\Validation\Rule::unique('users')->ignore($this->user()->id)]
    ];
}

P.S: I have added some other rules, i.e. required and email, in order to make this example clear for newbies.


One simple solution.

In your Model

protected $rules = [
    'email_address' => 'sometimes|required|email|unique:users',
    ..
];

In your Controller, action:update

...
$rules = User::$rules;
$rules['email_address'] = $rules['email_address'] . ',id,' . $id;
$validationCertificate  = Validator::make($input, $rules); 

There is an elegant way to do this. If you are using Resource Controllers, your link to edit your record will look like this:

/users/{user}/edit OR /users/1/edit

And in your UserRequest, the rule should be like this :

public function rules()
{
    return [
        'name' => [
            'required',
            'unique:users,name,' . $this->user
        ],
    ];
}

Or if your link to edit your record look like this:

/users/edit/1

You can try this also:

public function rules()
{
    return [
        'name' => [
            'required',
            'unique:users,name,' . $this->id
        ],
    ];
}

From Laravel 5.7, this works great

use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::unique('users')->ignore($user->id),
    ],
]);

Forcing A Unique Rule To Ignore A Given ID: