2009-12-22 3 views
21

Прежде всего, позвольте мне сказать, что я вернулся к Rails (играл с ним время или два, но заставлял себя написать полный проект с ним сейчас, начатый вчера).Проверка модели собственности больше, чем другая

Теперь я пытаюсь проверить, что свойство модели (терминология?) Больше, чем другое. Это оказалось идеальным экземпляром для validates_numericality_of с опцией greater_than, но, увы, это вызывает ошибку, указывающую мне greater_than expects a number, not a symbol. Если я попытаюсь привить этот символ .to_f, то я получу ошибку undefined method.

Вот что я в итоге сделал, и мне любопытно, есть ли лучший способ. Это просто простая система управления релизами проекта, у нас есть только основные/незначительные релизы (одноточечные), поэтому float чувствовал, что это правильное решение здесь.

class Project < ActiveRecord::Base 
    validates_numericality_of :current_release 
    validates_numericality_of :next_release 
    validate :next_release_is_greater 

    def next_release_is_greater 
     errors.add_to_base("Next release must be greater than current release") unless next_release.to_f > current_release.to_f 
    end 
end 

Это работает - она ​​проходит соответствующую проверку блока (ниже для Вашего удовольствия), я просто интересно, если есть более простой способ - то, что я мог бы попробовать иначе.

Соответствующий тест блока:

# Fixture data: 
# PALS: 
#  name: PALS 
#  description: This is the PALS project 
#  current_release: 1.0 
#  next_release: 2.0 
#  project_category: 1 
#  user: 1 
def test_release_is_future 
    project = Project.first(:conditions => {:name => 'PALS'}) 
    project.current_release = 10.0 
    assert !project.save 

    project.current_release = 1.0 
    assert project.save 
end 

ответ

19

Как вы заметили, единственный способ - использовать пользовательский валидатор. Параметр: more_than должен быть целым числом. Следующий код не будет работать, поскольку текущая и следующая версия доступны только на уровне экземпляра.

class Project < ActiveRecord::Base 
    validates_numericality_of :current_release 
    validates_numericality_of :next_release, :greater_than => :current_release 
end 

Целью варианта greater_than является проверка значения против статического постоянная или другого метода класса.

Итак, не возражайте и продолжайте использовать свой валидатор. :)

+0

Отличный ответ, развернутый ответ - то, что мне нужно (плюс немного успокаиванию). –

+0

Отличный ответ, пожалуйста, исправьте орфографическую ошибку, когда у вас есть шанс «greather_than». Еще раз спасибо. – ghayes

+0

Выполнено, спасибо. –

0

Это самый лучший способ для выполнения пользовательской проверки, однако, вы можете захотеть взглянуть на что-то вроде factory_girl в качестве замены для светильников (которые он выглядит, как вы используете):

http://github.com/thoughtbot/factory_girl

Ваш аппарат тест будет выглядеть так:

def test_... 
    Factory.create(:project, :current_release => 10.0) 
    assert !Factory.build(:project, :current_release => 1.0).valid? 
end 
4

С Rails 3.2 вы можете проверять два поля друг против друга на лету, передавая в proc.

validates_numericality_of :next_release, :greater_than => Proc.new {|project| project.current_release } 
6

validates_numericality_of принимает a large list of options и некоторые из них могут быть поставлены с прока или символ (это означает, что вы можете в основном передать атрибут или весь метод).

для проверки numericality свойства является выше, чем другое значение:

class Project < ActiveRecord::Base 
    validates_numericality_of :current_release, less_than: ->(project) { project.next_release } 

    validates_numericality_of :next_release, 
    greater_than: Proc.new { project.current_release } 
end 

Для уточнения, любой из этих вариантов может принять процедурный или символ:

  • :greater_than
  • :greater_than_or_equal_to
  • :equal_to :less_than
  • :less_than_or_equal_to

validates_numericality документы:http://api.rubyonrails.org/classes/ActiveModel/Validations/HelperMethods.html#method-i-validates_numericality_of

используя проки с валидаций: http://guides.rubyonrails.org/active_record_validations.html#using-a-proc-with-if-and-unless