This library aids one in handling money and different currencies. Features:
-
Provides a Money class which encapsulates all information about an certain amount of money, such as its value and its currency.
-
Represents monetary values as integers, in cents. This avoids floating point rounding errors.
-
Provides APIs for exchanging money from one currency to another.
-
Has the ability to parse a money string into a Money object.
-
Provides ActiveRecord “has_money” method.
-
Autofetch rates from ECB
gem sources -a http://gems.github.com gem install <this-fork>-money
require 'money' # 10.00 USD money = Money.new(1000, "USD") money.cents # => 1000 money.currency # => "USD" money.format # => "$10.00" Money.new(880088, "EUR").format # => €8,800.88 Money.new(-8000).format(:no_cents => true) # => $-80 Money.new(1000, "USD") == Money.new(1000, "USD") # => true Money.new(1000, "USD") == Money.new( 100, "USD") # => false Money.new(1000, "USD") == Money.new(1000, "EUR") # => false
You can use round_to_coin when you don’t have currency with coins for cents. E.g. if the smallest coin is 0.50, then
Money.new(1448, 'CZK').round_to_coin(50).to_s # => "14.50"
Exchanging money is performed through an exchange bank object. The default exchange bank object requires one to manually specify the exchange rate. Here’s an example of how it works:
Money.add_rate("CAD", 0.803115) Money.add_rate("USD", 1.24515) Money.us_dollar(100_00).exchange_to("CAD") # => Money.new(15504, "CAD") Money.ca_dollar(100_00).exchange_to("USD") # => Money.new(6450, "USD")
or
Money.us_dollar(100).as_cad # => Money.new(155, "CAD") Money.ca_dollar(100).as_usd # => Money.new(64, "USD")
Comparison and arithmetic operations work as expected:
Money.new(1000, "USD") <=> Money.new(900, "USD") # => 1; 9.00 USD is smaller Money.new(1000, "EUR") + Money.new(10, "EUR") == Money.new(1010, "EUR") Money.add_rate("EUR", 0.5) Money.new(1000, "EUR") + Money.new(1000, "USD") == Money.new(1500, "EUR")
Fetch the exchange rates published by the European Bank
Money.default_bank.fetch_rates # Fetch the rates Money.default_bank.auto_fetch 3600 # Fetch the rates every hour Money.default_bank.stop_fetch # Stop auto-fetch
There is nothing stopping you from creating bank objects which scrapes www.xe.com for the current rates or just returns rand(2)
:
Money.default_bank = ExchangeBankWhichScrapesXeDotCom.new
If you already have a value in integer/float or a string which ruby can parse with ‘to_i`, use new. It’ll avoid the string parser, which is resource intensive.
Money defaults to USD as its currency. This can be overwritten using:
Money.default_currency = "CAD"
If you use Rails, then environment.rb is a very good place to put this.
By default, Money won’t fetch the rates automatically, you need to call: @some_bank.fetch_rates
If you have your bank default rates configured, it’ll fetch all possible rates from it, if you don’t, It’ll fetch all rates to and from your default_currency.
Money uses the ECB XML Feed. (ecb.int)
Use the has_money
method to embed the money object in your models. The following example requires a price_cents
and a price_currency
fields on the database.
config/enviroment.rb
require.gem 'bobek-money', :lib => 'money'
app/models/product.rb
class Product < ActiveRecord::Base belongs_to :product has_money :price validates_numericality_of :price_cents, :greater_than => 0 end
migration:
create_table :products do |t| t.integer :price_cents t.string :price_currency end
Check out meiaduzia.com.br/cuducos2/priceformat for a nice mask for webapp’s textfields.
Resources:
Orinally developed by:
-
Forked from: github.com/FooBarWidget/money
-
Website: money.rubyforge.org
-
RDoc API: money.rubyforge.org
This branch is part of: