我最近在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%中填入了正确的金额。
但是,有时它没有填充数据库中的2位数amount_payable
,而是填充其他一些奇怪的值,例如:
87.31999999999999
(其中87.32
是存储在SQLite数据库中的十进制类型值)
有人可以告诉我导致这种舍入错误的原因还是指向了正确的方向?
感谢您的帮助。
顺便说一句,这是我的数据库架构:
create_table "invoices", :force => true do |t|
t.decimal "amount_payable", :precision => 8, :scale => 2
end
答案 0 :(得分: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