2009-12-22 66 views
21

首先,让我说我是极其新新的Rails(玩弄它一两次,但迫使我自己现在写一个完整的项目,昨天开始)。验证模型属性大于另一个

我现在试图验证模型属性(术语?)是否比另一个更大。这似乎是validates_numericality_ofgreater_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

正如您注意到的,唯一的方法是使用自定义验证器。 :greater_than选项应该是一个整数。以下代码将不起作用,因为当前版本和下一版本仅在实例级别可用。

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

greater_than该选项的目的是为了验证对静态常数或其它类的方法的值。

因此,不要介意并继续使用您的自定义验证程序。 :)

+0

出色答卷,详细的回应 - 我需要的(加少许安慰)。 – 2009-12-22 16:05:11

+0

很好的答案,当你有机会“greather_than”时,请修复拼写错误。再次感谢。 – ghayes 2011-08-09 06:02:10

+0

完成,谢谢。 – 2011-08-09 08:48:19

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和它们中的一些可以与PROC或符号被提供(这意味着可以基本通过一个属性或整个方法)。

验证属性的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 

为了澄清,任何这些选项可以接受一个PROC或符号:

  • :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

相关问题