php

Laravel update model with unique validation rule for attribute

Problem

I have a Laravel User model whre I added unique validation rule on username and email. Now when I update my User through my Repo, and I want to re-validate my model, I get an error. This is how my update method looks like

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?

Solution

This is a common mistake in Laravel whenever you are updating anything. It will by default require id as a key in order to match the existing entry. So what you need to do is to append the id of the instance currently being updated to the validator.

Pass the id of your instance to ignore the unique validator.
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:

//validation rules
'email' => 'unique:users,email_address,' . $userId,
If creating, proceed as usual:

//validation rules
'email' => 'unique:users,email_address',

About the author

laravelrecipies