Active Record Precision十进制值被截断

时间:2015-04-28 15:01:24

标签: mysql ruby-on-rails-4 activerecord rails-activerecord

所以我有两个ActiveRecord模型,我将lat,lng值存储为小数。这两种模型对于lat,lng柱具有不同的精度和比例。

这是第一个:

 class Location1 < ActiveRecord::Migration

  def change
    create_table :locations1 do |t|
      t.decimal :lat, :precision => 8, :scale => 6, :null => false
      t.decimal :lng, :precision => 8, :scale => 6, :null => false
      t.timestamps
    end
   end

 end

第二个在这里:

  class Location2 < ActiveRecord::Migration

    def change
      create_table :locations2 do |t|
        t.decimal :lat, :precision => 10, :scale => 8, :null => false
        t.decimal :lng, :precision => 10, :scale => 8, :null => false
        t.timestamps
      end
    end

  end

所以我有这个奇怪的错误,对于lat / lng的某些值,后小数点值会四舍五入为零。

因此,对于Location1.create(:lat => 12.93475, :lng => 77.63199057430029)lng值会四舍五入为77.0。如果我删除一个小数位,lng值为77.6319905743002,则该值将正确存储为77.631991。但对于77.63199057430029之后的任意位数,该值将存储为77.0

我认为这只发生在某些值上,与小数点后的位数无关。即使像77.23423234234234234234234234234234这样的值也会正确存储为77.234232

这种情况在极少数情况下仅针对某些值发生。至少对于这个值,我在第二个有能力的Location2中没有问题。因此,使用Location2.create(:lat => 12.93475, :lng => 77.63199057430029)时,值会正确存储为77.631990574。所以我的猜测是它确实与精度和比例值有关,但不知道是什么。

知道这里发生了什么吗?

1 个答案:

答案 0 :(得分:0)

猜猜#1

它可能是你的数据库引擎吗?直接从数据库调查模式,而不是从schema.rb文件调查。数据存储方式的真实来源直接来自数据库。

我基本上想知道是否由于某种原因,即使你已经指定decimal,它也会被存储为float,并且你有某种舍入/存储问题。当然我不希望它一直转向77.0(你预计至少会有几个小数位,即使在舍入错误的情况下),但是我会看一下你的模式无论哪种方式。

猜猜#2

在保存过程之前,您是否有机会在存储值之前进行某种回调或代码(在您的代码库或任何支持宝石中)进行此舍入?也许你已经忘记或忽略了什么?

猜猜#3

ActiveRecord或您的数据库的特定于版本的问题?您是否研究过可能导致此问题的特定版本(或两者的组合)的错误?

您在这些方面对此问题做了哪些其他研究?