https://github.com/spk/money-open-exchange-rates
A gem that calculates the exchange rate using published rates from open-exchange-rates. Compatible with the money gem.
https://github.com/spk/money-open-exchange-rates
currency exchange-rate money
Last synced: about 1 month ago
JSON representation
A gem that calculates the exchange rate using published rates from open-exchange-rates. Compatible with the money gem.
- Host: GitHub
- URL: https://github.com/spk/money-open-exchange-rates
- Owner: spk
- License: mit
- Created: 2011-10-18T15:02:33.000Z (over 13 years ago)
- Default Branch: master
- Last Pushed: 2024-06-10T14:26:25.000Z (12 months ago)
- Last Synced: 2025-04-12T14:57:31.213Z (about 1 month ago)
- Topics: currency, exchange-rate, money
- Language: Ruby
- Homepage: https://spk.github.io/money-open-exchange-rates
- Size: 387 KB
- Stars: 112
- Watchers: 4
- Forks: 63
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: History.md
- License: LICENSE
Awesome Lists containing this project
README
# Money Open Exchange Rates
A gem that calculates the exchange rate using published rates from
[open-exchange-rates](https://openexchangerates.org/). Compatible with
[Money](https://github.com/RubyMoney/money#currency-exchange) [currency
exchange](http://www.rubydoc.info/gems/money/Money/Bank/VariableExchange).Check [api documentation](https://docs.openexchangerates.org/)
* [Live](https://docs.openexchangerates.org/docs/latest-json) and
[historical](https://docs.openexchangerates.org/docs/historical-json)
exchange rates for
[180 currencies](https://docs.openexchangerates.org/docs/supported-currencies).
* [Free plan](https://openexchangerates.org/signup) hourly updates, with USD
base and up to 1,000 requests/month.
* Automatically caches API results to file or Rails cache.
* Calculate pair rates.
* Automatically fetches new data from API if data becomes stale when
`ttl_in_seconds` option is provided.
* Support for black market and digital currency rates with `show_alternative`
option.## Installation
Add this line to your application's Gemfile:
``` ruby
gem 'money-open-exchange-rates'
```And then execute:
```
bundle
```Or install it yourself as:
```
gem install money-open-exchange-rates
```## Usage
``` ruby
require 'money/bank/open_exchange_rates_bank'# Memory store per default; for others just pass as argument a class like
# explained in https://github.com/RubyMoney/money#exchange-rate-stores
oxr = Money::Bank::OpenExchangeRatesBank.new(Money::RatesStore::Memory.new)
oxr.app_id = 'your app id from https://openexchangerates.org/signup'# Update the rates for the current rates storage
# If the storage is memory you will have to restart the server to be taken into
# account.
# If the storage is a database, file, this can be added to
# crontab/worker/scheduler `Money.default_bank.update_rates`
oxr.update_rates# (optional)
# See https://github.com/spk/money-open-exchange-rates#cache for more info
# Updated only when `refresh_rates` is called
oxr.cache = 'path/to/file/cache.json'# (optional)
# Set the seconds after than the current rates are automatically expired
# by default, they never expire, in this example 1 day.
# This ttl is about money store (memory, database ...) passed though
# `Money::Bank::OpenExchangeRatesBank` as argument not about `cache` option.
# The base time is the timestamp fetched from API.
oxr.ttl_in_seconds = 86400# (optional)
# Set historical date of the rate
# see https://openexchangerates.org/documentation#historical-data
oxr.date = '2015-01-01'# (optional)
# Set the base currency for all rates. By default, USD is used.
# OpenExchangeRates only allows USD as base currency
# for the free plan users.
oxr.source = 'USD'# (optional)
# Extend returned values with alternative, black market and digital currency
# rates. By default, false is used
# see: https://docs.openexchangerates.org/docs/alternative-currencies
oxr.show_alternative = true# (optional)
# Minified Response ('prettyprint')
# see https://docs.openexchangerates.org/docs/prettyprint
oxr.prettyprint = false# (optional)
# Refresh rates, store in cache and update rates
# Should be used on crontab/worker/scheduler `Money.default_bank.refresh_rates`
# If you are using unicorn-worker-killer gem or on Heroku like platform,
# you should avoid to put this on the initializer of your Rails application,
# because will increase your OXR API usage.
oxr.refresh_rates# (optional)
# Force refresh rates cache and store on the fly when ttl is expired
# This will slow down request on get_rate, so use at your on risk, if you don't
# want to setup crontab/worker/scheduler for your application.
# Again this is not safe with multiple servers and could increase API usage.
oxr.force_refresh_rate_on_expire = trueMoney.default_bank = oxr
Money.default_bank.get_rate('USD', 'CAD')
```## Refresh rates
### With [whenever](https://github.com/javan/whenever)
``` ruby
every :hour do
runner "Money.default_bank.refresh_rates"
# you will have to restart the server if you are using memory rate store
runner "Money.default_bank.update_rates"
end
```### With rake task
``` ruby
namespace :open_exchange_rates do
desc "Refresh rates from cache and update rates"
task :refresh_rates => :environment do
Money.default_bank.refresh_rates
# you will have to restart the server if you are using memory rate store
Money.default_bank.update_rates
end
end
```## Cache
You can also provide a `Proc` as a cache to provide your own caching mechanism
perhaps with Redis or just a thread safe `Hash` (global). For example:``` ruby
oxr.cache = Proc.new do |v|
key = 'money:exchange_rates'
if v
Thread.current[key] = v
else
Thread.current[key]
end
end
```With `Rails` cache example:
``` ruby
OXR_CACHE_KEY = "#{Rails.env}:money:exchange_rates".freeze
oxr.ttl_in_seconds = 86400
oxr.cache = Proc.new do |text|
if text
Rails.cache.write(OXR_CACHE_KEY, text)
else
Rails.cache.read(OXR_CACHE_KEY)
end
end
```To update the cache call `Money.default_bank.refresh_rates` on
crontab/worker/scheduler. This have to be done this way because the fetch can
take some time (HTTP call) and can fail.## Full example configuration initializer with Rails and cache
``` ruby
require 'money/bank/open_exchange_rates_bank'OXR_CACHE_KEY = "#{Rails.env}:money:exchange_rates".freeze
# ExchangeRate is an ActiveRecord model
# more info at https://github.com/RubyMoney/money#exchange-rate-stores
oxr = Money::Bank::OpenExchangeRatesBank.new(ExchangeRate)
oxr.ttl_in_seconds = 86400
oxr.cache = Proc.new do |text|
if text
# only expire when refresh_rates is called or `force_refresh_rate_on_expire`
# option is enabled
# you can also set `expires_in` option on write to force fetch new rates
Rails.cache.write(OXR_CACHE_KEY, text)
else
Rails.cache.read(OXR_CACHE_KEY)
end
end
oxr.app_id = ENV['OXR_API_KEY']
oxr.show_alternative = true
oxr.prettyprint = false# This can be removed if you have data to avoid http call on boot for production
oxr.update_ratesMoney.default_bank = oxr
```See also how to [refresh and update rates](#refresh-rates)
### Tests
To avoid to hit the API we can use the cache option with a saved file like this:
``` ruby
OXR_CACHE_KEY = "#{Rails.env}:money:exchange_rates".freeze
if Rails.env.test?
oxr.cache = Rails.root.join("test/fixtures/currency-rates.json").to_s
else
oxr.ttl_in_seconds = 5.minutes.to_i
oxr.cache = Proc.new do |text|
if text
Rails.cache.write(OXR_CACHE_KEY, text)
else
Rails.cache.read(OXR_CACHE_KEY)
end
end
end
```## Pair rates
Unknown pair rates are transparently calculated: using inverse rate (if known),
or using base currency rate to both currencies forming the pair.## Tests
```
bundle exec rake
```## Refs
*
*
*
*## Contributors
See [GitHub](https://github.com/spk/money-open-exchange-rates/graphs/contributors).
## License
The MIT License
Copyright © 2011-2023 Laurent Arnoud
---
[](https://gitlab.com/spkdev/money-open-exchange-rates/-/commits/master)
[](https://gitlab.com/spkdev/money-open-exchange-rates/-/commits/master)
[](https://rubygems.org/gems/money-open-exchange-rates)
[](http://www.rubydoc.info/gems/money-open-exchange-rates)
[](http://opensource.org/licenses/MIT "MIT")
[](http://inch-ci.org/github/spk/money-open-exchange-rates)