amountsPrecise fungible quantities for Ruby and Rails
One abstraction for money, tokens, commodities, inventory, and points — with atomic integer storage, registry-driven type safety, optional Rails persistence, and explicit conversion rules.
One abstraction for money, tokens, commodities, inventory, and points — with atomic integer storage, registry-driven type safety, optional Rails persistence, and explicit conversion rules.
amounts is for applications that need to answer questions like:
The gem treats all of those as the same core problem: a precise quantity of a registered fungible type.
The docs stay grounded in three recurring examples:
USDC, USD, and SOLGOLD with display units like grams and kilogramsLOGS for split and allocation examplesThose examples reappear across concepts, guides, Rails integration, and testing so the ideas build instead of resetting on every page.
require "amount"
Amount.register :USDC,
decimals: 6,
display_symbol: "$",
display_position: :prefix,
ui_decimals: 2
Amount.register :USD,
decimals: 2,
display_symbol: "$",
display_position: :prefix,
ui_decimals: 2
Amount.register :SOL,
decimals: 9,
display_symbol: "SOL",
display_position: :suffix,
ui_decimals: 4
Amount.register_default_rate :USD, :USDC, "1"
Amount.register_default_rate :USDC, :USD, "1"
payroll_buffer = Amount.usdc("125000.00")
invoice = Amount.new("2500.00", :USD)
(payroll_buffer - invoice).ui
# => "$122500.00"| Concern | amounts answer |
|---|---|
| Precision | Every amount stores atomic value as a Ruby Integer |
| Type identity | Types live in a registry, not a class hierarchy |
| Cross-type math | Allowed only when a directional rate exists |
| Display units | Scale presentation, not type conversion |
| Splits | Return [parts, remainder], never implicit favoritism |
| Rails | Optional adapter, not a core runtime dependency |
Common misread
The gem has a few deliberate distinctions that matter:
split and allocate expose remainder explicitlyThose points are what make the abstraction reliable. The Concepts section is designed to make them feel obvious before you reach for the API reference.