Class: OpenExchangeRatesClient

Inherits:
Object
  • Object
show all
Defined in:
lib/open_exchange_rates_client.rb

Overview

Client for the Open Exchange Rates API (https://openexchangerates.org).

Replaces the unmaintained money-historical-bank git gem, whose
money (~> 6) gemspec pin blocked the money 7.x upgrade. That gem's
Money::Bank surface (exchange_with, import_rates/export_rates,
the in-memory rate store) went entirely unused — ExchangeRate
only ever needed a single historical-rate lookup, which is all this
class provides.

OXR quotes every currency against USD, so an arbitrary pair reduces
to rates[to] / rates[from] with USD pinned at 1.0.

Constant Summary collapse

BASE_URL =
'https://openexchangerates.org/api'
REQUEST_TIMEOUT =
15

Instance Method Summary collapse

Constructor Details

#initialize(app_id: ENV.fetch('OPENEXCHANGERATES_APP_ID', nil)) ⇒ OpenExchangeRatesClient

Returns a new instance of OpenExchangeRatesClient.

Parameters:

  • app_id (String, nil) (defaults to: ENV.fetch('OPENEXCHANGERATES_APP_ID', nil))

    OXR application id; defaults to the
    OPENEXCHANGERATES_APP_ID env var.



20
21
22
# File 'lib/open_exchange_rates_client.rb', line 20

def initialize(app_id: ENV.fetch('OPENEXCHANGERATES_APP_ID', nil))
  @app_id = app_id
end

Instance Method Details

#rate(date, from, to) ⇒ Float?

Exchange rate from from to to effective on date.

Parameters:

  • date (Date)

    rate date; today uses OXR's /latest endpoint,
    earlier dates use /historical.

  • from (String, Symbol)

    ISO 4217 code to convert from

  • to (String, Symbol)

    ISO 4217 code to convert to

Returns:

  • (Float, nil)

    the rate, or nil when OXR has no usable
    data for date (or either currency is absent from the response)



32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/open_exchange_rates_client.rb', line 32

def rate(date, from, to)
  from = from.to_s.upcase
  to = to.to_s.upcase
  return 1.0 if from == to

  rates = rates_for(date)
  return nil if rates.blank?

  from_rate = from == 'USD' ? 1.0 : rates[from]
  to_rate   = to == 'USD' ? 1.0 : rates[to]
  return nil unless from_rate && to_rate

  to_rate.to_f / from_rate
end