Проверка свойства модели важнее другого - PullRequest
27 голосов
/ 22 декабря 2009

Во-первых, позвольте мне сказать, что я чрезвычайно новичок в 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

Ответы [ 4 ]

24 голосов
/ 22 декабря 2009

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

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

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

Так что, не возражайте и продолжайте свой собственный валидатор. :)

9 голосов
/ 02 декабря 2013

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

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

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

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

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

validates_numericity документы: 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

6 голосов
/ 27 апреля 2013

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

validates_numericality_of :next_release, :greater_than => Proc.new {|project| project.current_release }
0 голосов
/ 22 декабря 2009

Это лучший способ выполнить пользовательскую проверку, однако вы можете захотеть рассмотреть что-то вроде 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 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...