Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чому правило unique не гарантує унікальність і що робити?

Правило unique - це SELECT перед вставкою. Між перевіркою й записом інший запит встигає вставити той самий email.

Запит A: SELECT ... email = 'a@x.com'   -> немає
Запит B: SELECT ... email = 'a@x.com'   -> немає
Запит A: INSERT a@x.com                 -> ок
Запит B: INSERT a@x.com                 -> дубль

Що робити:

  1. Унікальний індекс у базі - єдина справжня гарантія. Валідація лишається для зрозумілого повідомлення в нормальному випадку.
  2. Обробити порушення індексу - Laravel кидає UniqueConstraintViolationException, його перетворюють на ту саму помилку валідації. Або createOrFirst(), який робить це сам.
try {
    $user = User::create($data);
} catch (UniqueConstraintViolationException) {
    throw ValidationException::withMessages(['email' => __('validation.unique', ['attribute' => 'email'])]);
}

Деталі правила, про які питають:

  • при оновленні виключають поточний запис: Rule::unique('users')->ignore($user->id); ignore() ніколи не беруть з даних запиту - лише з моделі, інакше клієнт підставить чужий ID;
  • withoutTrashed() не враховує м'яко видалені записи;
  • регістр: Ada@x.com і ada@x.com різні для unique, тож email нормалізують до нижнього регістру ще до валідації.

Докладніше в документації: Правило unique

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання