Почему масштаб BigDecimal изменяется при доступе через ассоциацию?

У меня есть две модели Ruby on Rails Farm и Harvest. Ферма принадлежит урожаю. Вот модели:

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

Есть только одна Ферма (достигнутая благодаря действиям как одноэлементный драгоценный камень). Каждый раз, когда собирают урожай, ассоциация урожая с фермы меняется, так как всегда должна указывать на последний урожай. Поскольку я использую ферму как одноэлементную модель, я обновляю ферму, используя следующий код:

@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

Итак, что здесь происходит? Сумма должна быть точно такой же!


person Sofia Bravo    schedule 15.02.2016    source источник


Ответы (1)


Я понял. Масштаб и точность не имели смысла. Точность - это количество цифр в BigDecimal, масштаб - это количество тех цифр, которые появляются справа от десятичной точки. Поскольку точность была установлена ​​на 6, шкала не могла вместить 8 цифр после десятичной точки. Поэтому, когда число поступало из базы данных, оно было усечено, когда оно поступало из памяти, все его цифры стояли после десятичной точки. Я исправил это, установив точность на 18 и масштаб на 8, что означает 18 цифр всего и 8 из тех, которые появляются справа от десятичной точки.

Sqlite допускал некогерентную точность => 6 и масштаб => 8. Postgres этого не делал.

person Sofia Bravo    schedule 15.02.2016