0

I have a lot of currencies in a database table that includes the code (EUR USD GBP...) and a "fxrate" which is the exchange rate of each currency to USD.

Table structure:

+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| id         | int(11)     | NO   | PRI | NULL    | auto_increment |
| ccode      | varchar(20) | YES  |     | NULL    |                |
| cname      | varchar(20) | YES  |     | NULL    |                |
| csign      | varchar(50) | YES  |     | NULL    |                |
| fxrate     | float       | YES  |     | NULL    |                |
| created_at | datetime    | YES  |     | NULL    |                |
| updated_at | datetime    | YES  |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+

I want to be able to do things like:

25.15.eur.to_jpy

or

1500.usd.to_gbp

Because right now I am just writing lots of code to find and convert.

amount_eur = amount_gbp*Currency.where(:ccode => "GBP").first.fxrate/Currency.where(:ccode => "EUR").first.fxrate

Note: I don't want to define a method for each currency, I am tracking hundreds of them. Each has an unique ISO3 code.

Nick M
  • 2,424
  • 5
  • 34
  • 57
  • 1
    Yep, good idea. Go do it. :) – Sergio Tulentsev Dec 02 '17 at 13:48
  • If, say, in a week you do not succeed, ping me, I'll share mine. Wrote it to facilitate calculation of my expenses after trips abroad. :) So I can do things like `(30.jpy + 20.eur).to_usd` If you don't need this currency math, then the task becomes quite simple. – Sergio Tulentsev Dec 02 '17 at 13:51
  • Actually your first message made me think about possible consequences on framework and application level. Probably going to encapsulate it in the Currency class...after all it's only 10 more letters to type. – Nick M Dec 02 '17 at 13:53
  • Encapsulation is good, but then you don't be able to say `15.usd`? – Sergio Tulentsev Dec 02 '17 at 13:59
  • 1
    If I extend Float class I can do with 15.from_usd.to_eur, no big deal. If adding method to Currency class it does not matter how it gets called. – Nick M Dec 02 '17 at 14:10
  • Ah, you mean, put the main logic to `Currency`, but leave the sugar too? – Sergio Tulentsev Dec 02 '17 at 14:13
  • Yes sir, that is right. – Nick M Dec 02 '17 at 14:15
  • In this case, the consequencies are the same (the logic is still reachable through the floats). Just the structure of the code is better. – Sergio Tulentsev Dec 02 '17 at 14:16
  • 4
    An important thing to note is that for *serious* applications, you should **never** use `Float`s for money. You can use an `Integer` to store the number as "cents", or maybe use *two* integers. Or you can use a `String`, or a `BigDecimal`. But never a float (or double). This is due to rounding errors caused by floating point numbers. It applies to *all* languages, not just ruby. – Tom Lord Dec 02 '17 at 15:18
  • 2
    For more information, see [here](https://stackoverflow.com/a/3730040/1954610) for instance. Note that there already exists several implementations of "money" integrations into Rails, such as [this](https://github.com/RubyMoney/money-rails); none of which will use `Float`s. – Tom Lord Dec 02 '17 at 15:20

0 Answers0