我正在研究一个非常基本的购物车系统。
我有一个表items
,其列price
为integer
类型。
我无法在包括欧元和美分在内的价格中显示价格值。 就Rails框架中的处理货币而言,我是否遗漏了一些明显的东西?
#1楼
处理货币的常用做法是使用十进制类型。 以下是“使用Rails进行敏捷Web开发”的简单示例
add_column :products, :price, :decimal, :precision => 8, :scale => 2
这将允许您处理从-999,999.99到999,999.99的价格
您可能还希望在项目中包含验证
def validate
errors.add(:price, "should be at least 0.01") if price.nil? || price < 0.01
end
理智 - 检查你的价值观。
#2楼
您可能希望在数据库中使用DECIMAL
类型。 在迁移中,执行以下操作:
# precision is the total number of digits
# scale is the number of digits to the right of the decimal point
add_column :items, :price, :decimal, :precision => 8, :scale => 2
在Rails中, :decimal
类型作为BigDecimal
返回,这对于价格计算很有用。
如果你坚持使用整数,你将不得不手动转换到BigDecimal
的所有地方,这可能只是一个痛苦。
正如mcl所指出的,要打印价格,请使用:
number_to_currency(price, :unit => "€")
#=> €1,234.01
#3楼
绝对是整数 。
即使BigDecimal在技术上存在, 1.5
仍将为您提供Ruby中的纯Float。
#4楼
使用虚拟属性(链接到修订(付费)Railscast),您可以将price_in_cents存储在整数列中,并在产品模型中添加虚拟属性price_in_dollars作为getter和setter。
# Add a price_in_cents integer column
$ rails g migration add_price_in_cents_to_products price_in_cents:integer
# Use virtual attributes in your Product model
# app/models/product.rb
def price_in_dollars
price_in_cents.to_d/100 if price_in_cents
end
def price_in_dollars=(dollars)
self.price_in_cents = dollars.to_d*100 if dollars.present?
end
来源: RailsCasts#016: 虚拟属性 : 虚拟属性是添加不直接映射到数据库的表单字段的简洁方法。 在这里,我将展示如何处理验证,关联等。
#5楼
如果有人使用续集,迁移将看起来像:
add_column :products, :price, "decimal(8,2)"
不知怎的,Sequel忽略了:精确度和:规模
(续集版本:续集(3.39.0,3.38.0))
来源:oschina
链接:https://my.oschina.net/u/3797416/blog/3197689