My form request has 'email' => 'required|email|unique:users' and it works on create, but when I edit a user and keep the same email I get "The email has already been taken". How do I ignore the current record?
DEV3 Developer Forum
Why does my unique validation fail when updating a record in Laravel?
Ask a question
Every post is reviewed first. Usually reviewed within 24 hours.
dev3 ·
0
1 reply
dev3 · Accepted answer
The unique rule checks the whole table, including the row you are editing. You must tell it which row to ignore.
use Illuminate\Validation\Rule;
public function rules(): array
{
return [
'email' => [
'required', 'email',
Rule::unique('users', 'email')->ignore($this->route('user')),
],
];
}
ignore() accepts a model instance or an id. With route model binding $this->route('user') is the model. If your primary key is not id:
Rule::unique('users')->ignore($user->uuid, 'uuid');
Scoping uniqueness (e.g. unique per tenant or per team):
Rule::unique('projects', 'slug')
->where('team_id', $this->user()->team_id)
->ignore($this->project);
Soft deletes: by default soft deleted rows still count as taken. Use ->withoutTrashed() to ignore them, but also remember the DB unique index still blocks the insert, so a composite unique index with deleted_at or a restore flow is needed.
Pitfalls
- Never pass raw user input to
ignore(), such asignore($request->input('id')), because a user can send another record's id. Use the route-bound model or the authenticated user. - Validation is not a guarantee under concurrency. Always keep a unique index in the database and handle
UniqueConstraintViolationException. - On create,
ignore(null)is harmless, so one form request can serve both create and update.
0