Я использую Разрешение для аутентификации в моем приложении направляющих. Clearance::User
смешивание добавляет несколько проверок к моему User
модель, но существует один из них, что я хотел бы удалить или переопределить. Каков лучший способ сделать это?
Рассматриваемая проверка
validates_uniqueness_of :email, :case_sensitive => false
который сам по себе не плох, но я должен был бы добавить :scope => :account_id
. Проблема - это, если я добавляю это к моему User
модель
validates_uniqueness_of :email, :scope => :account_id
Я получаю обе проверки, и одно Разрешение добавляет, более строго, чем мой, таким образом, мой не имеет никакого эффекта. Я должен удостовериться та единственная шахта выполнения. Как я делаю это?
В итоге я "решил" проблему следующим образом:
:email
типа :taken
Звучит разумно, пока вы не прочитаете код и не узнаете, как я удаляю ошибку. ActiveRecord::Errors
не имеет методов для удаления ошибок после их добавления, поэтому мне приходится хвататься за его внутренности и делать это самому. Супер-пупер-мега-уродливо.
Вот код:
def validate
super
remove_spurious_email_taken_error!(errors)
end
def remove_spurious_email_taken_error!(errors)
errors.each_error do |attribute, error|
if error.attribute == :email && error.type == :taken && email_unique_for_account?
errors_hash = errors.instance_variable_get(:@errors)
if Array == errors_hash[attribute] && errors_hash[attribute].size > 1
errors_hash[attribute].delete_at(errors_hash[attribute].index(error))
else
errors_hash.delete(attribute)
end
end
end
end
def email_unique_for_account?
match = account.users.find_by_email(email)
match.nil? or match == self
end
Если кто-то знает лучший способ, я буду очень благодарен.
У меня недавно была эта проблема, и после того, как Google не дал мне ответы достаточно быстро, я нашел более аккуратное, но все еще неидеальное решение этой проблемы . Теперь это не обязательно сработает в вашем случае, поскольку кажется, что вы используете уже существующие суперклассы, но для меня это был мой собственный код, поэтому я просто использовал параметр: if с проверкой типа в суперклассе.
def SuperClass
validates_such_and_such_of :attr, :options => :whatever, :if => Proc.new{|obj| !(obj.is_a? SubClass)}
end
def SubClass < SuperClass
validates_such_and_such_of :attr
end
В случае подклассов, состоящих из нескольких файлов
def SuperClass
validates_such_and_such_of :attr, :options => :whatever, :if => Proc.new{|obj| [SubClass1, SubClass2].select{|sub| obj.is_a? sub}.empty?}
end
def SubClass1 < SuperClass
validates_such_and_such_of :attr
end
def SubClass2 < SuperClass
end