Answers:
您可能需要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
任何地方手动与s进行相互转换,这可能会很痛苦。
正如mcl指出的那样,要打印价格,请使用:
number_to_currency(price, :unit => "€")
#=> €1,234.01
这是一种很好的简单方法 composed_of
(使用ValueObject模式的ActiveRecord的一部分)和Money gem
你需要
Product
integer
,模型(和数据库)中的列:price
将此写入您的product.rb
文件中:
class Product > ActiveRecord::Base
composed_of :price,
:class_name => 'Money',
:mapping => %w(price cents),
:converter => Proc.new { |value| Money.new(value) }
# ...
您会得到:
product.price = "$12.00"
自动转换为Money类product.price.to_s
显示十进制格式的数字(“ 1234.00”)product.price.format
显示正确格式的货币字符串product.price.cents.to_s
处理货币的常见做法是使用十进制类型。这是“使用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
理智地检查您的价值观。
对于RoR开发中一些有抱负的初级/初学者,只需稍作更新,并汇总所有答案,就一定会在这里进行一些解释。
使用:decimal
存储钱DB,作为@molf建议(什么我公司使用的金标准与金钱工作时)。
# 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
几点:
:decimal
将被用来BigDecimal
解决很多问题。
precision
并scale
应根据您所代表的内容进行调整
如果您使用收款和发送付款方式,precision: 8
并且scale: 2
给您999,999.99
最高的金额,那么在90%的情况下可以。
如果您需要代表房地产或稀有汽车的价值,则应使用更高的precision
。
如果使用坐标(经度和纬度),则肯定需要更高的scale
。
要使用上述内容生成迁移,请在终端中运行:
bin/rails g migration AddPriceToItems price:decimal{8-2}
要么
bin/rails g migration AddPriceToItems 'price:decimal{5,2}'
如本博客文章所述。
亲吻额外的库,并使用内置的帮助器。number_to_currency
按照建议使用@molf和@facundofarias。
要number_to_currency
在Rails控制台中使用帮助程序,请将呼叫发送到ActiveSupport
的NumberHelper
类,以访问该帮助程序。
例如:
ActiveSupport::NumberHelper.number_to_currency(2_500_000.61, unit: '€', precision: 2, separator: ',', delimiter: '', format: "%n%u")
提供以下输出
2500000,61€
检查其他options
的number_to_currency帮手。
您可以将其放在应用程序助手中,并在视图内部使用任意数量。
module ApplicationHelper
def format_currency(amount)
number_to_currency(amount, unit: '€', precision: 2, separator: ',', delimiter: '', format: "%n%u")
end
end
或者,您可以将其Item
作为实例方法放入模型中,并在需要设置价格格式的地方(在视图或助手中)调用它。
class Item < ActiveRecord::Base
def format_price
number_to_currency(price, unit: '€', precision: 2, separator: ',', delimiter: '', format: "%n%u")
end
end
还有一个示例,说明我如何使用number_to_currency
控制器内部(注意该negative_format
选项,用于表示退款)
def refund_information
amount_formatted =
ActionController::Base.helpers.number_to_currency(@refund.amount, negative_format: '(%u%n)')
{
# ...
amount_formatted: amount_formatted,
# ...
}
end
使用虚拟属性(链接到经修订(收费)的Railscast的链接),您可以将price_in_cents存储在整数列中,并在产品模型中添加虚拟属性price_in_dollars作为获取器和设置器。
# 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:虚拟属性:虚拟属性是添加不直接映射到数据库的表单域的一种干净方法。在这里,我展示了如何处理验证,关联等等。
您可以将一些选项传递给number_to_currency
(标准的Rails 4视图助手):
number_to_currency(12.0, :precision => 2)
# => "$12.00"
正如Dylan Markow发布的
Ruby&Rails的简单代码
<%= number_to_currency(1234567890.50) %>
OUT PUT => $1,234,567,890.50
DECIMAL(19, 4)
是一个流行的选择,请在此检查并在此处检查世界货币格式以确定要使用的小数位数,希望有所帮助。