What is the best method of handling currency/money

2019-01-01 13:56发布

I'm working on a very basic shopping cart system.

I have a table items that has a column price of type integer.

I'm having trouble displaying the price value in my views for prices that include both Euros and cents. Am I missing something obvious as far as handling currency in the Rails framework is concerned?

13条回答
姐姐魅力值爆表
2楼-- · 2019-01-01 14:23

You can pass some options to number_to_currency (a standard Rails 4 view helper):

number_to_currency(12.0, :precision => 2)
# => "$12.00"

As posted by Dylan Markow

查看更多
深知你不懂我心
3楼-- · 2019-01-01 14:25

If someone is using Sequel the migration would look something like:

add_column :products, :price, "decimal(8,2)"

somehow Sequel ignores :precision and :scale

(Sequel Version: sequel (3.39.0, 3.38.0))

查看更多
残风、尘缘若梦
4楼-- · 2019-01-01 14:28

If you are using Postgres (and since we're in 2017 now) you might want to give their :money column type a try.

add_column :products, :price, :money, default: 0
查看更多
孤独寂梦人
5楼-- · 2019-01-01 14:34

Common practice for handling currency is to use decimal type. Here is a simple example from "Agile Web Development with Rails"

add_column :products, :price, :decimal, :precision => 8, :scale => 2 

This will allow you to handle prices from -999,999.99 to 999,999.99
You may also want to include a validation in your items like

def validate 
  errors.add(:price, "should be at least 0.01") if price.nil? || price < 0.01 
end 

to sanity-check your values.

查看更多
一个人的天荒地老
6楼-- · 2019-01-01 14:34

Use money-rails gem. It nicely handles money and currencies in your model and also has a bunch of helpers to format your prices.

查看更多
裙下三千臣
7楼-- · 2019-01-01 14:36

You'll probably want to use a DECIMAL type in your database. In your migration, do something like this:

# 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

In Rails, the :decimal type is returned as BigDecimal, which is great for price calculation.

If you insist on using integers, you will have to manually convert to and from BigDecimals everywhere, which will probably just become a pain.

As pointed out by mcl, to print the price, use:

number_to_currency(price, :unit => "€")
#=> €1,234.01
查看更多
登录 后发表回答