Tin*_*n81 0 ruby ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2
我最近在Rails中遇到了这个奇怪的错误.
class PaymentsController < ApplicationController
def new
@payment = current_user.payments.build(:invoice_id => params[:invoice_id])
@title = "Make payment"
end
end
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
当我这样称呼这个动作时invoice......
<%= link_to "Make payment", new_payment_path(:invoice_id => invoice.id) %>
Run Code Online (Sandbox Code Playgroud)
...付款表单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
Run Code Online (Sandbox Code Playgroud)
你永远不应该将Money存储为浮点数 - 这里发生的是浮点运算,这对于用钱计算是很常见的.
更好的一点是将所有内容存储为整数美分.因此,您可能在数据库中有一个"amount_in_cents"列,它是一个整数.
然后,为'amount'添加一个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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
372 次 |
| 最近记录: |