我正在开发一个非常基本的购物车系统。
我有一个表items,它的列价格类型为整型。
我在视图中显示包含欧元和美分的价格时遇到了麻烦。在Rails框架中处理货币时,我是否遗漏了一些明显的东西?
我正在开发一个非常基本的购物车系统。
我有一个表items,它的列价格类型为整型。
我在视图中显示包含欧元和美分的价格时遇到了麻烦。在Rails框架中处理货币时,我是否遗漏了一些明显的东西?
当前回答
使用Virtual Attributes(链接到修订的(付费)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:虚拟属性:虚拟属性是添加不直接映射到数据库的表单字段的一种干净的方式。在这里,我将展示如何处理验证、关联等。
其他回答
下面是一个利用composed_of (ActiveRecord的一部分,使用ValueObject模式)和Money宝石的简单方法
你需要
金钱宝石(4.1.0版本) 一个模型,例如Product 模型(和数据库)中的整数列,例如:price
把这些写进你的产品中。rb文件:
class Product > ActiveRecord::Base
composed_of :price,
:class_name => 'Money',
:mapping => %w(price cents),
:converter => Proc.new { |value| Money.new(value) }
# ...
你会得到:
Without any extra changes, all of your forms will show dollars and cents, but the internal representation is still just cents. The forms will accept values like "$12,034.95" and convert it for you. There's no need to add extra handlers or attributes to your model, or helpers in your view. product.price = "$12.00" automatically converts to the Money class product.price.to_s displays a decimal formatted number ("1234.00") product.price.format displays a properly formatted string for the currency If you need to send cents (to a payment gateway that wants pennies), product.price.cents.to_s Currency conversion for free
如果你正在使用Postgres(因为我们现在已经是2017年了),你可能想尝试一下他们的:money列。
add_column :products, :price, :money, default: 0
Ruby和Rails的简单代码
<%= number_to_currency(1234567890.50) %>
OUT PUT => $1,234,567,890.50
您可能希望在数据库中使用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
使用Virtual Attributes(链接到修订的(付费)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:虚拟属性:虚拟属性是添加不直接映射到数据库的表单字段的一种干净的方式。在这里,我将展示如何处理验证、关联等。