我正在研究一个很是基本的购物车系统。 git
我有一个表items
,其列price
为integer
类型。 数据库
我没法在包括欧元和美分在内的价格中显示价格值。 就Rails框架中的处理货币而言,我是否遗漏了一些明显的东西? app
处理货币的经常使用作法是使用十进制类型。 如下是“使用Rails进行敏捷Web开发”的简单示例 框架
add_column :products, :price, :decimal, :precision => 8, :scale => 2
这将容许您处理从-999,999.99到999,999.99的价格
您可能还但愿在项目中包含验证 spa
def validate errors.add(:price, "should be at least 0.01") if price.nil? || price < 0.01 end
理智 - 检查你的价值观。 code
您可能但愿在数据库中使用DECIMAL
类型。 在迁移中,执行如下操做: ci
# 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
的全部地方,这可能只是一个痛苦。 get
正如mcl所指出的,要打印价格,请使用: 产品
number_to_currency(price, :unit => "€") #=> €1,234.01
绝对是整数 。
即便BigDecimal在技术上存在, 1.5
仍将为您提供Ruby中的纯Float。
使用虚拟属性(连接到修订(付费)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: 虚拟属性 : 虚拟属性是添加不直接映射到数据库的表单字段的简洁方法。 在这里,我将展现如何处理验证,关联等。
若是有人使用续集,迁移将看起来像:
add_column :products, :price, "decimal(8,2)"
不知怎的,Sequel忽略了:精确度和:规模
(续集版本:续集(3.39.0,3.38.0))