@Dmitriy Kiriyenko

ActiveRecord и валидация на уникальность

Кто знает - напоминаю, кто не знает - сообщаю: валидация в ActiveRecord на уникальность не гарантирует уникальности. Как она работает - делает запрос в базу данных на предмет "а есть ли уже запись с таким значением", а при получении отрицательного ответа - ничтоже сумняшеся начинает сохранять. Если в этот момент в базе запись-таки появится - будет нарушение уникальности.

Если вы думаете, что это не про вас, и у вас в приложении полтора пользователя, а нагрузка для этого эффекта нужна посерьёзнее - вы заблуждаетесь, и заряженный арбалет уже нацелен на ваше колено. Мы вот тоже думали, что это не про нас, но...

Гарантию уникальности даст индекс с проверкой уникальности. Но он не дёргает ошибку валидации.

Я тут немного поговнокодил и сделал drop-in решение, простое, как стол - если сохранение падает по причине нарушенного database constraint, перевалидировать и вернуть false. Таким образом, код пойдёт по ветке контроллера для ошибок валидации, и ошибка нарушенной уникальности отобразится обычными средствами на форме.

Я не проверяю, что вы выставили и валидацию, и индекс. За этим нужно следить самому.

Может, кому-то это окажется полезным. В любом случае, не оставляйте валидацию на уникальность в коде модели без поддержки уникального индекса в базе.

Пользуйтесь!

blog comments powered by Disqus