首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何配置money-rails宝石以比4位数字更高的精度工作

如何配置money-rails宝石以比4位数字更高的精度工作
EN

Stack Overflow用户
提问于 2020-03-13 14:07:24
回答 1查看 999关注 0票数 2

我们在应用程序中使用money-rails gem。直到现在,我们还好有4个十进制数字的精度,但我们需要切换到6。不幸的是,我无法存储更高的精度数字到Postgres -数字是四舍五入的,然后保存。

代码语言:javascript
复制
class MyModel < ApplicationRecord
  monetize :price_cents # :price_cents, :decimal, default: 0, precision: 30, scale: 10
end

金钱本身似乎运作良好,精度更高。

代码语言:javascript
复制
pry(main)> Money.new(181.123456789).to_f
=> 1.81123456789

控制台中的测试模型。在保存前一切正常。

代码语言:javascript
复制
my_model = MyModel.find(1)
my_model.price = Money.new(181.123456789)
my_model.price.to_f # => 1.81123456789
my_model.save
my_model.price.to_f # => 1.8112

而ActiveRecord输出则表示修剪后的数字实际上正在发送到数据库。(注意到181.12)。

代码语言:javascript
复制
UPDATE "my_models" SET "price_cents" = $1 ... [["price_cents", "181.12"] ...]

有什么方法可以让money-rails gem更精确地工作吗?看起来,货币宝石本身就没有更高的精度问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-13 15:20:09

这种行为来源于钱的四舍五入,要关闭它,请使用:

代码语言:javascript
复制
Money.infinite_precision = true

下面是测试:

代码语言:javascript
复制
require "bundler/inline"

gemfile(ENV['INSTALL']=='1') do
  source "https://rubygems.org"
  gem "rails", '~>6.0'
  gem "sqlite3"
  gem 'money-rails'
end

require "minitest/autorun"
require "logger"
require "active_record"
require 'money-rails'

ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
  create_table(:models, force: true){|t| t.decimal :price_cents, default: 0, precision: 30, scale: 10 }
end

# to remove config warnings:
Money.locale_backend = :currency
Money.default_currency= :usd

# actual fix:
Money.infinite_precision = true

MoneyRails::Hooks.init # in a normal app is called automatically


class Model < ActiveRecord::Base
  monetize :price_cents 
end

class BugTest < Minitest::Test
  def test_association_stuff
    m = Model.create!(price_cents: 181.123456789).reload
    assert_equal 181.123456789, m.price_cents
    assert_equal 1.81123456789, m.price.to_f

    m2 = Model.create(price: Money.new(182.123456789)).reload
    assert_equal 1.82123456789, m2.price.to_f
  end
end
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60671933

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档