2011-11-09 30 views
1

我需要在我的模型来验证数据,然后使用RSpec的测试这种模式时失败测试寿模型这样验证使用validates_presence_of和validates_numericality_of

it { should validate_presence_of :sales_price } 
it { should validate_presence_of :retail_price } 
it { should validate_numericality_of :sales_price } 
it { should validate_numericality_of :retail_price } 

我得到这个错误

Failure/Error: it { should validate_presence_of :retail_price } 
ArgumentError: 
    comparison of Float with nil failed 
# ./spec/models/offer_option_spec.rb:19:in `block (2 levels) in <top (required)>' 

我该如何解决这个问题?

+0

也许另一种方式来看看它:你需要'validates_presence_of'?因为validates_numericality_of已经确保'retail_price'不是零。看起来很奇怪,它适用于'sales_price',但不适用于'retail_price'您使用什么值进行测试? – sled

回答

3

谢谢您的回答。

我终于明白了。

validates_numericality_of :sales_price, :greater_than => 0, 
         :allow_blank => true 
validates_numericality_of :retail_price, :greater_than => 0, 
         :allow_blank => true 
validates_numericality_of :sales_price, :less_than => :retail_price, 
         :if => Proc.new { |o| !o.retail_price.nil? } , 
         :message => "can't be greater than retail price." 

现在我又遇到了另一个问题。我使用rails.validation.js,它可以帮助我执行客户端验证。一切都OK了,如果你在你的数字验证使用这样的:

:greater_than => 0 

validation.js创建检查,如果在字段中的值大于0的功能是创建一个这样的功能:

new Function("return " + element.val() + CHECKS[check] + options[check])())) 

元件是我的输入字段, CHECKS包含不同的散列:LESS_THAN:<,GREATER_THAN:>等 选项【检查】包含传递到验证一些值(:在这种情况下GREATER_THAN => 0,零,选项[检查] less_than:'0')。但是,当我用别的东西来代替值的我得到一个错误:

Uncaught ReferenceError: retail_price is not defined 

我想是这样的

validates_numericality_of :sales_price, :less_than => Proc.new{ self.retail_price }, 
         :if => Proc.new { |o| !o.retail_price.nil? } , 
         :message => "can't be greater than retail price." 

,但在执行验证时,对象不存在,所以只是自我指向类和retail_price不存在。

你会推荐什么来解决这个问题?

+0

尝试将'less_than' proc更改为'Proc.new {| o | o.retail_price}' - 与'if' proc相同的方法。 –

3

@sled是正确的,无效检查内置到validates_numericality_of中,默认情况下启用,所以没有必要同时具备这两个要求。

还有一点要注意的是,销售价格确实是两次验证数字性,这可能会导致问题。我会改为

validates_numericality_of :sales_price, :greater_than => 0, :less_than => :retail_price, :message => "must be less than retail price." 
+0

是的,我不确定你是否可以像这样堆叠校验器 - 如果不是这样的话,应该都是一个整体,然后是清晰/局部的。 –

相关问题