Ruby on Rails十进制比较停止工作

时间:2019-01-06 17:08:08

标签: ruby-on-rails ruby

我一直在使用数据库中的状态对象,该状态对象跟踪哪些种子数据已加载到其中。该表的结构为:

return false

seeds.rb文件检查database_version并运行代码块,然后在运行该块后设置database_version。从版本0.1到0.55都可以正常工作。

我添加了一个新的种子数据块。要运行该块,请检查database_version,它应为0.56。以下比较无效:

create_table "toolkit_states", force: :cascade do |t|
  t.boolean "signups", default: true
  t.decimal "database_version", precision: 5, scale: 2
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

由于某些原因,无法对数字0.56与数据库中存储的值进行相等性评估。它已经处理了所有高达0.56的值。

这是一个Rails控制台会话:

if state.database_version == 0.56

当我用“ to_f”转换值时,比较有效。我的问题是,如果不进行此转换(最高转换值为0.56),它会很好地工作

2 个答案:

答案 0 :(得分:1)

之所以发生,是因为state.database_versionBigDecimal类的实例。 This article解释为什么是BigDecimal

看这个例子:

BigDecimal('0.56e0')
=> 0.56e0
irb(main):008:0> BigDecimal('0.56e0') == 0.56
=> false
irb(main):009:0> BigDecimal('0.56e0').to_f
=> 0.56

如您所见,在转换为0.56e0后,float的类型变为0.56,并且比较返回true。

内特(Nate)更简要地解释了为什么发生这种情况in this comment

答案 1 :(得分:0)

irb(main):001:0>  c = BigDecimal('0.56e0')
=> 0.56e0
irb(main):002:0> c == 0.56
=> false
irb(main):003:0>  c = BigDecimal('0.55e0')
=> 0.55e0
irb(main):004:0> c == 0.55
=> true

适用于0.55而不适用于0.56 Rails的错误吗?