【问题标题】:Why does a BigDecimal scale changes if accessed through an association?如果通过关联访问,为什么 BigDecimal 比例会发生变化?
【发布时间】:2016-02-15 17:02:20
【问题描述】:

我有两个 Ruby on Rails 模型 FarmHarvest。农场属于收获。以下是模型:

class Farm < ActiveRecord::Base
  acts_as_singleton
  belongs_to :harvest
  validates :harvest, presence: true, allow_blank: true
  serialize :harvest_time, Tod::TimeOfDay
  validates :harvest_time, presence: true, allow_blank: true
  validates :hash_rate, presence: true
  validates_with HashRateValidator
end

class Harvest < ActiveRecord::Base
  belongs_to :user
  validates :user, presence: true
  validates :date, presence: true
  validates :amount, presence: true
  validates :identifier, presence: true
  validates :amount, numericality: { :greater_than => 0 }
end

只有一个农场(感谢作为单身宝石的行为)。每次收获完成时,农场的收获关联都会改变,因为它总是必须指向最新的收获。由于我使用 Farm 作为单例模型,因此我使用以下代码更新 Farm:

@harvest = Harvest.new(
      :date => DateTime.now,
      :amount => amount,
      :identifier => new_identifier,
      :user => current_user,
      :assigned => false
)

if @harvest.save
   Farm.instance.update_attributes(:harvest => @harvest)
   byebug

奇怪的是收获量的值与分配给农场的收获量的值在此之后不匹配:

(byebug) Farm.instance.harvest.amount
435.435

(byebug) @harvest.amount
435.435345343

(byebug) Farm.instance.harvest.id
12

(byebug) @harvest.id
12

数量小数应该有 8 位和 6 位精度(来自迁移),这里是 schema.rb 文件的相关部分:

create_table "harvests", force: :cascade do |t|
    t.datetime "date"
    t.decimal  "amount",                          precision: 6, scale: 8
    t.integer  "identifier"
    t.datetime "created_at",                                                              null: false
    t.datetime "updated_at",                                                              null: false
    ...
  end

那么,这里发生了什么?金额应该是完全相同的值!

【问题讨论】:

    标签: ruby-on-rails ruby bigdecimal


    【解决方案1】:

    我想通了。规模和精度没有意义。精度是 BigDecimal 数量上的位数,比例是出现在小数点右侧的那些数字的数量。由于精度设置为 6 刻度无法容纳小数点后 8 位。因此,当数字来自数据库时,它被截断,当它来自内存时,它的所有数字都在小数点后。 我通过将精度设置为 18 并将比例设置为 8 来修复它,这意味着总共 18 位数字,其中 8 位出现在小数点右侧。

    Sqlite 允许不连贯的精度 => 6 和规模 => 8。Postgres 不允许。

    【讨论】:

      猜你喜欢
      • 2020-08-25
      • 1970-01-01
      • 2020-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      • 2015-09-18
      相关资源
      最近更新 更多