2010-07-27 33 views
3

認爲我有一個遷移如下不能理解導軌ActiveRecord的類型轉換原因

create_table :dummies do |t| 
    t.decimal :the_dummy_number 
end 

我實例像下面

dummy = Dummy.new 
dummy.the_dummy_number = "a string" 
puts dummy.the_dummy_number 

輸出用於上述是

0.0 

這是怎麼發生的?因爲我分配一個錯誤的值不應該會引發錯誤?

最大的問題是以下幾點。

因爲它會自動轉換我驗證方法失敗慘敗。

更新 -the validate方法

validate :is_dummy_number_valid, :the_dummy_number 
def is_dummy_number_valid 
    read_attribute(:the_dummy_number).strip() 
end 
+0

你使用什麼驗證方法?如果您使用'validates_numericality_of:the_dummy_number',它應該可以正常工作 – 2010-07-27 09:22:14

+0

檢查更新 – ZX12R 2010-07-27 09:27:52

+0

您的驗證方法不會進行任何驗證! – 2010-07-27 09:51:38

回答

3

的原因,當你想到的是,當傳遞一個字符串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_numericality_of宏使用RAW_VALUE方法的價值得到它之前類型轉換並分配給內部十進制值。

+0

非常感謝你.. – ZX12R 2010-07-27 09:56:09

相關問題