这不能像您预期的那样工作的原因是BigDecimal的底层ruby实现在传递字符串时不会出错。
考虑以下代码
[ 'This is a string', '2is a string', '2.3 is also a string',
' -3.3 is also a string'].each { |d| puts "#{d} = #{BigDecimal.new(d)}" }
This is a string = 0.0
2is a string = 2.0
2.3 is also a string = 2.3
-3.3 is also a string = -3.3
所以BigDecimal扫描字符串,并将字符串开头可能是十进制的任何内容赋给它的值。
如果你把模特摆成这样
class Dummy < ActiveRecord::Base
validates_numericality_of :the_dummy_number
end
那么验证就可以了
>> d=Dummy.new(:the_dummy_number => 'This is a string')
=> #<Dummy id: nil, the_dummy_number: #<BigDecimal:5b9230,'0.0',4(4)>, created_at: nil, updated_at: nil>
>> puts d.the_dummy_number
0.0
=> nil
>> d.valid?
=> false
>> d.errors
=> #<ActiveRecord::Errors:0x5af6b8 @errors=#<OrderedHash
{"the_dummy_number"=>[#<ActiveRecord::Error:0x5ae114
@message=:not_a_number, @options={:value=>"This is a string"}
这是因为validates\u numericability\u宏使用raw\u value方法在值被类型转换并赋给内部十进制值之前获取该值。