Ruby 和金钱,在 Rails 应用程序中,如何在数据库中存储金钱值?

问题描述 投票:0回答:5

我想确保在 Rails 应用程序中存储产品价格时不存在舍入问题。

我应该使用什么 mysql 数据类型,它在 Rails 中映射到什么?

我想要 10 位小数以保证精度。

ruby-on-rails ruby currency
5个回答
16
投票

我更喜欢将货币作为最低面额的整数(便士、美分等)存储在数据库中,并据此进行计算。

add_column :product, :price, :integer

当然,您会希望任何表单输入和显示都是人们期望的形式,因此我们向模型添加一些辅助方法来帮助实现这一点。

class Product < ActiveRecord::Base
  def price_dollars
    self.price / 100
  end

  def price_dollars=(val)
    self.price = val * 100
  end
end

在控制台中我们得到:

> prod = Product.new
=> [snip]

> prod.price_dollars = 12.93
=> 12.93
> prod.price
=> 1293
> prod.price_dollars
=> 12.93

> prod.price = 1691
=> 1691
> prod.price_dollars
=> 16.91

我确信可能有一个插件可以很好地处理这个问题。


13
投票

听起来您想要

:decimal
列类型。您可以使用
:precision
:scale
选项控制总位数和小数位数:

add_column :mytable, :mycolumn, :decimal, :precision => 30, :scale => 10

更多关于数据类型的信息请参见 本文档


1
投票

我认为将最小公分母作为整数存储在数据库中总是最简单的(这里有一个我们使用美分的问题:在 Ruby on Rails 中处理国际货币输入,但是如果您可以将价格存储为 1/10,000 美分)像),并在从数据库中取出数字时进行正确的数学计算。


1
投票

添加道格拉斯上面的出色答案:

为了让它工作,至少在 Ruby 2.1.4 中,您需要在除以 100 时将 :price 字段转换为浮点数或小数。

一个整数除以另一个整数

1293 / 100

不会返回您可能期望的结果。 Ruby 没有返回 12.93,而是返回 12 整数。

2.1.4 :002 > 1293 / 100
=> 12
2.1.4 :003 > 1293.to_f / 100
=> 12.93

产品型号代码示例

class Product < ActiveRecord::Base
  def price_dollars
    self.price.to_f / 100
  end

  def price_dollars=(val)
    self.price = val * 100
  end
end


-9
投票

使用“浮动”

add_column :customer, :amount, :float
© www.soinside.com 2019 - 2024. All rights reserved.