ruby-on-rails - 无法理解 rails activerecord typecast 的原因

标签 ruby-on-rails ruby 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

how did this happen? since i assign a wrong value shouldn't it raise an error?

最大的问题如下。

因为它自动转换我的 validate 方法失败得很惨。

更新-验证方法

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

最佳答案

这不能像您预期的那样工作的原因是 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 方法获取在类型转换和分配给内部十进制值之前的值。

关于ruby-on-rails - 无法理解 rails activerecord typecast 的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3342137/

相关文章:

javascript - 如何处理 Rails to_json 输出中的 HTML 实体?

ruby-on-rails - rails : Couldn't find a file for 'twitter/bootstrap'

ruby-on-rails - 取消继承的 STI 模型的关联

mysql - 表中一定数量的列后 ActiveRecord 出现问题

ruby - Rails 3 查询 : Find all Posts with the same Topic

ruby-on-rails - 将参数从 View 传递到 Controller

ruby-on-rails - Sprockets::FileNotFound 尝试包含 jQuery gem 时

mysql - Windows 上的全新 Ruby on Rails 安装 : MSQL Gem Not Working

Ruby:从 Ruby 中的变量创建散列键和值

ruby-on-rails - 如何阻止 Rails Controller 中的业务逻辑