propster
propster

Reputation: 577

Storing Prices with Cents in Rails

Ok I have a Stripe charge to which I am applying taxes. Stripe takes in a number as cents, so it leaves you with a number like 10015 instead of 100.15.

In my controller, I am sending the number to ActiveRecord as 10015/100.0

When I retrieve it, it gives me #<BigDecimal:7fca81f71130,'0.1243E3',18(27)>>

Whats going on ?

I tried

rails g migration add_expense_to_user expense:integer

and

rails g migration add_expense_to_user expense:decimal

to whose migration I added

add_column :user, :expense, :decimal, precision: 6, scale: 2

which is the current setup.

How do I store / retrieve the value if it is stored as 10015/100

Upvotes: 2

Views: 918

Answers (3)

Holger Just
Holger Just

Reputation: 55833

The value is stored inside the BigDecimal object with arbitrary precision. The "common" representation of non-integer values (i.e. floats) however doesn't provide this precision. Thus, BigDecimal provides various options to convert its value to other types.

You can e.g use expense.to_f to get a floating point representation of the BigDecimal value (and thus loosing the precision along the way). Alternatively, if you just want to print the value, you could use one of the to_s method to format the value as a string:

expense.to_s
# => "124.3"

See the BigDecimal documentation for details.

Upvotes: 0

smathy
smathy

Reputation: 27971

The BigDecimal is just the type that Rails uses for decimal types in DBs. 0.1243E3 is scientific notation, short for 0.1243 x 10³ - ie. 124.3

You can get a regular float from it by just using the .to_f method in Ruby, or you can pass a BigDecimal into other Rails helpers, like number_to_currency(the_big_decimal) will produce "$124.30"

So, in other words, with the BigDecimal you probably already have what you're asking for in this question.

Upvotes: 1

alephtwo
alephtwo

Reputation: 322

When you access the data, you need to call .to_f.

In irb:

a = BigDecimal.new(5, 2)
a
=> #<BigDecimal:1ad7c98,'0.5E1',9(27)> 
a.to_f
=> 5.0

Upvotes: 1

Related Questions