用美分存储价格 Rails

Storing Prices with Cents in Rails

好的,我有一笔 Stripe 费用,我要对其征税。 Stripe 接受一个数字作为分,所以它给你留下一个像 10015 而不是 100.15 这样的数字。

在我的控制器中,我将数字作为 10015/100.0 发送到 ActiveRecord

当我检索它时,它给了我 #<BigDecimal:7fca81f71130,'0.1243E3',18(27)>>

怎么回事?

我试过了

rails g migration add_expense_to_user expense:integer

rails g migration add_expense_to_user expense:decimal

我添加了谁的迁移

add_column :user, :expense, :decimal, precision: 6, scale: 2

这是当前设置。

如果值存储为 10015/100,我该如何存储/检索该值

访问数据时,需要调用.to_f

在 irb 中:

a = BigDecimal.new(5, 2)
a
=> #<BigDecimal:1ad7c98,'0.5E1',9(27)> 
a.to_f
=> 5.0

BigDecimal 就是 Rails 在 DB 中用于 decimal 类型的类型。 0.1243E3 是科学计数法,是 0.1243 x 10³ 的缩写 - 即。 124.3

您可以通过 Ruby 中的 .to_f 方法从中获取常规浮点数,或者您可以将 BigDecimal 传递给其他 Rails 助手,例如number_to_currency(the_big_decimal) 将产生 "4.30"

因此,换句话说,有了 BigDecimal,您可能已经有了您在这个问题中所要求的内容。

该值以任意精度存储在 BigDecimal 对象中。然而,非整数值(即浮点数)的 "common" 表示不提供这种精度。因此,BigDecimal 提供了多种选项来将其值转换为其他类型。

例如,您可以使用 expense.to_f 来获取 BigDecimal 值的浮点表示形式(因此在此过程中会失去精度)。或者,如果您只想打印值,可以使用 to_s 方法之一将值格式化为字符串:

expense.to_s
# => "124.3"

详情见BigDecimal documentation