Проверки Rails для методов создания и обновления

#ruby-on-rails #postgresql #validation

Вопрос:

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

 
  def uniq_email
    errors.add(:email, "Already existing User with email: #{email}") if
      User.exists?(email: email)
  end
 

Это хорошо работает. Проблема в том, что, когда я хочу обновить этого пользователя, если я попытаюсь изменить электронное письмо на уже существующее, это позволит мне это сделать.
Я попытался добавить [:создать, :обновить] при проверке, но если я сделаю это, например, когда я изменю адрес, он снова запустит проверку модели и сообщит мне, что пользователь с этим электронным письмом уже существует.
Какая-нибудь помощь? Как я могу этого избежать?

Спасибо 😀

Комментарии:

1. apidock.com/rails/ActiveRecord/Validations/ClassMethods/…

Ответ №1:

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

 class User < ActiveRecord::Base
  validates_uniqueness_of :email
  # or
  validates :email, uniqueness: true
end
 

Чтобы сделать уникальность пуленепробиваемой, в бд следует добавить уникальный индекс электронной почты. Если по какой-либо причине вы обойдете проверки в модели, база данных выдаст сообщение об ошибке.

 class MakeEmailUnique < ActiveRecord::Migration
  def change
    add_index :users, :email, unique: true
  end
end
 

Вам следует ознакомиться с документами по проверке документов, чтобы узнать больше о том, как их использовать.

Комментарии:

1. Это правильно, насколько это касается проверок. Я только хотел добавить, что следует также добавить уникальный индекс электронной почты в базу данных для реальной защиты. Эта проверка полезна для получения сообщений об ошибках, но она не гарантирует уникальности.

2. Да, конечно, это должно быть удвоено ограничением уникальности. Будет обновляться.

3. @SergioTulentsev Готово.