Minting::Rails
Minting::Rails brings Minting money objects to Active Record models.
It adds a money_attribute model helper, registers a :mint_money Active Record type, and includes small convenience methods such as 12.to_money(:USD), 12.dollars, and '12.00'.mint(:BRL).
What it does
- Stores and reads model attributes as
Mint::Moneyobjects. - Supports composed money attributes backed by amount and currency columns.
- Normalizes numeric, string, and
Mint::Moneyassignments. - Validates currencies against the currencies enabled in Minting.
Requirements
- Ruby 3.3 or newer.
- Rails 7.1.3.2 or newer.
- Minting 1.0.0 or newer.
Installation
Add the gem to your Rails application's Gemfile:
gem 'minting-rails'
Install it:
bundle install
Generate the initializer:
bin/rails g mint:initializer
Configuration
Configure Minting in config/initializers/minting.rb:
Mint.configure do |config|
config.enabled_currencies = :all
config.default_currency = 'USD'
end
You can limit the currencies that may be used:
Mint.configure do |config|
config.enabled_currencies = %w[USD EUR BRL]
config.default_currency = 'USD'
end
You can also register custom currencies before enabling or using them:
Mint.configure do |config|
config.added_currencies = [
{ currency: 'CRC', subunit: 2, symbol: 'CRC' },
{ currency: 'NGN', subunit: 2, symbol: 'NGN' }
]
config.enabled_currencies = :all
config.default_currency = 'CRC'
end
The default currency must be registered and included in enabled_currencies.
Usage
Declare money attributes in your Active Record models with money_attribute.
Single-column fixed currency
Use this when a column always stores one currency, such as a price column that is always USD.
Migration:
class CreateProducts < ActiveRecord::Migration[7.1]
def change
create_table :products do |t|
t.decimal :price
t.decimal :discount
t.
end
end
end
Model:
class Product < ApplicationRecord
money_attribute :price, currency: 'USD'
money_attribute :discount, currency: 'USD'
end
Assignments are normalized to Mint::Money:
product = Product.new(price: 12, discount: '3.50')
product.price
# => #<Mint::Money ... USD 12.00>
product.discount
# => #<Mint::Money ... USD 3.50>
Assigning a Mint::Money with a different currency raises ArgumentError:
Product.new(price: 12.to_money(:EUR))
# raises ArgumentError because the attribute only accepts USD
Amount and currency columns
Use this when each row can store a different currency per record.
Migration:
class CreateOffers < ActiveRecord::Migration[7.1]
def change
create_table :offers do |t|
t.decimal :price_amount
t.string :price_currency
t.
end
end
end
Model:
class Offer < ApplicationRecord
money_attribute :price
end
The attribute is composed from price_amount and price_currency:
offer = Offer.new(price: 15.to_money(:EUR))
offer.price
# => #<Mint::Money ... EUR 15.00>
offer.price_amount
# => 15.0
offer.price_currency
# => "EUR"
When you assign a plain number or string, Minting::Rails uses Mint.default_currency:
offer = Offer.new(price: '12')
offer.price.currency_code
# => "USD"
Custom column names
If your amount and currency columns do not follow the <name>_amount and <name>_currency convention, pass a mapping:
class Invoice < ApplicationRecord
money_attribute :total, mapping: {
total_amount: :amount,
currency_code: :currency
}
end
The mapping keys are your database columns. The values must identify which column stores the :amount and which stores the :currency.
Querying
Fixed-currency attributes can be queried with Mint::Money values:
Product.where(price: 15.to_money(:USD))
Composed attributes can also be queried with a money object:
Offer.where(price: 15.to_money(:EUR))
You can still query the backing columns directly when that is clearer:
Offer.where(price_amount: 15, price_currency: 'EUR')
Convenience methods
Minting::Rails adds a few small helpers:
12.to_money(:USD)
12.mint(:BRL)
12.dollars
12.euros
'12.50'.to_money(:USD)
'12.50'.mint(:BRL)
These return Mint::Money instances.
Development
Clone the repository and install dependencies:
bundle install
Run the test suite:
bundle exec rake test
The repository includes a dummy Rails application under test/dummy for exercising the engine in a Rails environment.
Releasing
Update the version in lib/minting/money_attribute/version.rb, update release notes, and build the gem:
gem build minting-rails.gemspec
Publishing is configured for RubyGems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at gferraz/minting-rails.
Before opening a pull request, please run:
bundle exec rake test
License
The gem is available as open source under the terms of the MIT License.