Ruby和money,在rails应用程序中,如何在db中存储货币值?

时间:2011-02-21 23:52:23

标签: ruby-on-rails ruby currency

我想确保在轨道应用程序中存储产品价格时没有舍入问题。

我应该使用什么mysql数据类型,以及它在rails中映射到什么内容?

我希望小数位数精确到10位。

5 个答案:

答案 0 :(得分:13)

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

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

我确信可能有一个插件可以在某处妥善处理。

答案 1 :(得分:11)

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

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

this documentation中有关数据类型的更多内容(不知道column函数是什么,但可能是内部的!)。

希望这有帮助!

答案 2 :(得分:2)

增加道格拉斯上面的优秀答案:

为了使它起作用,至少在Ruby 2.1.4中,你需要在除以100时将:price字段转换为float或decimal。

将整数除以另一个整数

1293/100

不会返回您的预期。而不是 12.93 Ruby返回 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

答案 3 :(得分:1)

我认为将最低公分母作为整数存储在数据库中总是最容易的(这里是我们使用美分的问题:Handling international currency input in Ruby on Rails,但如果你愿意,可以存储1 / 10,000美分的价格),从数据库中取出数字时,请执行正确的数学运算。

答案 4 :(得分:-7)

使用“float”

add_column :customer, :amount, :float