class ExchangeRate::RateSources::ECBRateRetriever
Retrieves FX rates from the 90 day European Central Bank (ECB) feed.
Constants
- DEFAULT_FEED_URL
The ECB feed URL
Public Class Methods
Builds a new ECBRateRetriever
.
-
feed_url - The URL to request the ECB feed from.
# File lib/exchange_rate/rate_sources/e_c_b_rate_retriever.rb, line 21 def initialize(feed_url: DEFAULT_FEED_URL) @feed_url = feed_url end
Public Instance Methods
Retrieve the feed, parse the contents, and update the local cache.
Returns nothing Raises ExchangeRate::RetrievalFailedError
if the feed could not be loaded Raises ExchangeRate::RetrievalFailedError
if the cache could not be updated
# File lib/exchange_rate/rate_sources/e_c_b_rate_retriever.rb, line 35 def save! retrieve_feed .yield_self { |feed_body| parse_feed(feed_body) } .map { |rate_date_hash| rates_from(rate_date_hash, date_from(rate_date_hash)) } .flatten .map(&:save) nil rescue StandardError raise ExchangeRate::RetrievalFailedError end
Private Instance Methods
Creates or updates the local cache of the currency/rate/date tuple
currency - The currency short-code, e.g. 'GBP'. value_in_euro - The value of one unit (e.g. $1) in Euro. date_of_rate - The date this value applies to.
Returns true if the record saved Raises ExchangeRate::RetrievalFailedError
if the record could not be saved
# File lib/exchange_rate/rate_sources/e_c_b_rate_retriever.rb, line 110 def create_or_update_currency_rate(currency:, value_in_euro:, date_of_rate:) rate = CurrencyRate.find_or_new(currency: currency, date_of_rate: date_of_rate) rate.value_in_euro = value_in_euro rate.tap(&:save) rescue Sequel::ValidationFailed, Sequel::HookFailed raise ExchangeRate::RetrievalFailedError end
Extract the effective date of an FX rate.
rate_date_hash - A single currency/date/rate ::Hash object.
Returns the effective ::Date of the FX rate.
# File lib/exchange_rate/rate_sources/e_c_b_rate_retriever.rb, line 84 def date_from(rate_date_hash) Date.parse(rate_date_hash['time']) end
Parse the ECB feed XML into an array of feed ::Hash objects.
feed_body - The XML ECB feed document as a String.
Returns an array of currency/date/rate ::Hash objects, grouped by date (see rate_array_from
).
# File lib/exchange_rate/rate_sources/e_c_b_rate_retriever.rb, line 63 def parse_feed(feed_body) Hash.from_xml(feed_body) .yield_self { |feed_hash| rate_array_from(feed_hash) } end
Extract the array of FX rates from the XML document.
feed_hash - A ::Hash representation of the XML ECB feed document.
Returns An array of date/rate/currency ::Hash objects, grouped by date.
# File lib/exchange_rate/rate_sources/e_c_b_rate_retriever.rb, line 74 def rate_array_from(feed_hash) feed_hash['Envelope']['Cube']['Cube'] end
Builds an array of ExchangeRate::CurrencyRate
objects.
rate_date_array - An array of currency/rate ::Hash objects rate_effective_date - The effective ::Date for FX rates in the rate_date_hash.
# File lib/exchange_rate/rate_sources/e_c_b_rate_retriever.rb, line 93 def rates_from(rate_date_array, rate_effective_date) rate_date_array['Cube'].map do |currency_rate_hash| create_or_update_currency_rate(currency: currency_rate_hash['currency'], value_in_euro: currency_rate_hash['rate'].to_f, date_of_rate: rate_effective_date) end end
Perform the HTTP request to grab the feed contents.
Returns the response body as a String.
# File lib/exchange_rate/rate_sources/e_c_b_rate_retriever.rb, line 52 def retrieve_feed uri = URI.parse(@feed_url) Net::HTTP.get_response(uri).body end