RubyMoney/money-rails

`monetize`'d attribute assignment of number as subunits?

wwahammy opened this issue · 3 comments

First off, really great tool, I'm enjoying it so far. I have a quirky situation that I need to handle and I'm not sure if money-rails supports it.

The basic issue is that I don't want an assignment of a number being treated as if units were passed. As an example, right now, let's say I have a model like so:

class CustomModel < ApplicationRecord
  monetize :amount_cents
end

Assuming my currency is 'USD', if I new up an instance of CustomModel like so:

CustomModel.new(amount: {cents: 1000})

the amount attribute is now set to an instance of money with 1000 cents ($10) and USD as the currency.

On the other hand, if I do the following:

CustomModel.new(amount: 1000)

the amount attribute is an instance with 100,000 cents ($1000) and USD as the currency. In other words, it converts it the number from a unit to a subunit.

For my API, I want it to always treat numbers passed in as a subunit. What I'm looking for is for CustomModel.new(amount: 1000) to create a Money object with the same value as the first example, i.e. 1000 cents and 'USD'.

Is there any way to do this using money-rails? If not, would a contribution to add this feature be welcome and if so, are there any suggestions on how such a feature should be designed and function?

We welcome a PR that adds new options so long as it does not break currently understood behavior

sunny commented

@wwahammy Are you still interested in this? Wouldn’t calling amount_cents: 1000 when you want to store the subunit instead of amount: 1000 fix your use-case?

@wwahammy Are you still interested in this? Wouldn’t calling amount_cents: 1000 when you want to store the subunit instead of amount: 1000 fix your use-case?

@sunny I am still interested in it. I think I started a PR on this but I never got it over the finish line.

Calling amount_cents: 1000 would work but for us is a bit of a leaky abstraction. There's no situation where we'd ever want our API to accept anything other than the smallest subunit. For us and I'd assume a number of other people dealing with financial values (Stripe for example), everything is canonically handled in the smallest unit (cents for USD). Any time dollars are used, that's simply a display convenience.