Проблема пользовательской проверки ActiveRecord - PullRequest
0 голосов
/ 26 ноября 2009

У меня проблема с проверкой в ​​моей модели RoR:

def save
  self.accessed = Time.now.to_s
  self.modified = accessed
  validate_username
  super
end
def validate_username
  if User.find(:first, :select => :id, :conditions => ["userid = '#{self.userid}'"])
    self.errors.add(:userid, "already exists")
  end
end

Как вы можете видеть, я заменил метод сохранения модели своим собственным, вызывая validate_username, прежде чем я вызову родительский метод .save. Моя проблема в том, что, хотя ошибка добавляется, Rails все еще пытается вставить новую строку в базу данных, даже если имя пользователя является дубликатом. Что я тут не так делаю?

PS: я не использую validate_uniqueness_of из-за следующей проблемы с чувствительностью к регистру: https://rails.lighthouseapp.com/projects/8994/tickets/2503-validates_uniqueness_of-is-horribly-inefficient-in-mysql

Обновление: я попробовал решение weppos, и оно работает, но не совсем так, как хотелось бы. Теперь поле помечается как неправильное, но только если все остальные поля верны. Я имею в виду, что, если я, например, введу неправильный адрес электронной почты, поле электронной почты будет помечено как неисправное, поле ИД пользователя - нет. Когда я отправляю правильный адрес электронной почты, поля идентификатора пользователя помечаются как неправильные. Надеюсь, вы, ребята, понимаете, о чем я: D

Обновление 2: данные должны проверяться таким образом, чтобы не было возможности вставлять дубликаты идентификаторов пользователей в базу данных без учета регистра. Идентификаторы пользователя имеют формат «пользовательский домен», например. "Test-something.net". К сожалению, validates_uniqueness_of :userid не работает, он пытается вставить «test-something.net» в базу данных, даже если «Test-something.net» уже существует. validate_username должен был быть моим (быстрым) решением этой проблемы, но это не сработало. Решение weppos работало, но не совсем так, как я хочу (как объяснялось в моем первом обновлении).

Еще не понял ... кто-нибудь?

С наилучшими пожеланиями, x3ro

Ответы [ 2 ]

5 голосов
/ 26 ноября 2009

Почему бы вам не использовать обратный вызов и оставить метод сохранения без изменений? Также избегайте прямой интерполяции значений SQL.

class ... < ActiveRecord::Base

  before_save :set_defaults
  before_create :validate_username

  protected

  def set_defaults
    self.accessed = Time.now.to_s
    self.modified = accessed
  end

  def validate_username
    errors.add(:userid, "already exists") if User.exists?(:userid => self.userid)
    errors.empty?
  end

end
0 голосов
/ 26 ноября 2009

Как насчет вызова super, только если validate_username возвращает true или что-то подобное?

def save
  self.accessed = Time.now.to_s
  self.modified = accessed
  super if validate_username
end
def validate_username
  if User.find(:first, :select => :id, :conditions => ["userid = '#{self.userid}'"])
    self.errors.add(:userid, "already exists")
    return false
  end
end

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

...