Reputation: 79
I have a database-table cost with the columns amount and currency. I search for a solution to save a currency into this column.
What do you suggest: Which data type for the column currency and what values should I save there (iso-code, currency symbol ...)? Or maybe there is already a data type Currency in ruby like in java?
Upvotes: 3
Views: 5288
Reputation: 176472
In general, you save the amounts as integers, because floating point are known to have rounding errors that are definitely not suitable for representing money.
Because money can have fractions, it's quite common that the integer represents the amount in cent, so that you can easily perform operations on the amounts, then divide by /100
to get the value as dollars.
The money
gem is the most popular library in Ruby to deal with currencies and money. Internally, the library uses exactly the same approach I just described. Actually, the library was moved in the past to use BigDecimal which are a Ruby-specific library for dealing with arbitrary precision integer arithmetic.
If you want to use it in Rails, the money-rails
gem is a quick solution. However, you are not required to use this gem, nor the money
gem, especially if your need is limited to that specific model and basic operations.
It's your choice. However, you should really represent amounts in integers. As for currencies, you can use simple varchar fields and use the 3-char standard representation.
Upvotes: 3
Reputation: 782
Here are all the Rails 4 (ActiveRecord migration) datatypes:
:binary
:boolean
:date
:datetime
:decimal
:float
:integer
:primary_key
:references
:string
:text
:time
:timestamp
Source: Rails 4: List of available datatypes
As you can see there is no data type currency. I suggest you to create a decimal column for the amount and an integer for the currency.
Why integer? Well because you can set an enum for that column in your model like this:
enum currency: [:dollar]
This creates a method with the same name as the enum, so let's say you have a cost variable:
cost.dollar?
This will return true or false depending on the value.
Also with this you can easily create some case to make all the changes in currency you like:
case cost.currency
when Cost.currencies[:dollar]
# Do something
end
Always compare this column with Cost.currencies[:symbol_of_currency] instead of the number (enums work just like C, 0 would be the first element), this will allow you to change the order of the elements inside the enum or add new ones without changing the functionality of your app.
Also, this allows you to create the rows in the database like this:
Cost.create(currency: :dollar, amount: 30.0, ...)
Upvotes: 4