DEV3 Technologies home

DEV3 Developer Forum

Why does my unique validation fail when updating a record in Laravel?

Laravel helpSolved0 views
dev3 ·

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?

#laravel#validation#eloquent

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 as ignore($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

Your reply

Every post is reviewed by DEV3 before it appears. Usually reviewed within 24 hours.

Markdown supported. Use ``` for code blocks. Images are not allowed.