0

我最近在 Rails 中遇到了这个奇怪的错误。

class PaymentsController < ApplicationController

  def new
    @payment = current_user.payments.build(:invoice_id => params[:invoice_id])
    @title = "Make payment" 
  end

end

class Payment < ActiveRecord::Base

  attr_accessible :amount, :date, :invoice_id

  after_initialize :set_amount

  private

  def set_amount
    if new_record? && invoice.present?
      self.amount ||= invoice.amount_payable
    end
  end

end

当我这样称呼这个动作时invoice......

<%= link_to "Make payment", new_payment_path(:invoice_id => invoice.id) %>

...付款表单显示invoice在下拉字段中预选正确(这是正确的)。

amount在大约 90% 的情况下,付款的金额都是正确的。

但是,有时它不会填充amount_payable数据库中的 2 位数字,而是填充一些其他奇怪的值,例如:

87.31999999999999

87.32SQLite数据库中存储的十进制类型值在哪里)

有人可以告诉我是什么导致了这个舍入错误或指出我正确的方向吗?

谢谢你的帮助。

顺便说一句,这是我的数据库架构:

create_table "invoices", :force => true do |t|
  t.decimal  "amount_payable", :precision => 8, :scale => 2
end
4

1 回答 1

5

您永远不应该将 Money 存储为浮点数 --- 这里发生的是浮点运算,这对于使用金钱进行计算非常常见。

更好的一点是将所有内容存储为美分的整数。因此,您的数据库中可能有一个整数列“amount_in_cents”。

然后,为“金额”添加一个 getter/setter,以便您可以#amount在任何地方使用。

class Payment < ActiveRecord::Base

  def amount
    amount_in_cents / 100.0
  end

  def amount=(other)
    self.amount_in_cents = (other * 100).to_i
  end
end
于 2013-03-31T18:35:37.190 回答