In Ruby on Rails, we can use to_json
to convert data or hash to JSON easily, but we need to be cautious when we convert numeric data to JSON in Rails. In this article we are going to share about how Rails treats BigDecimal differently besides other numeric data type.
Rails serializes BigDecimal as string when we convert to JSON
# store float number to variable float_number
pry(main)> float_number = Float 123
=> 123.0
# store big decimal number to variable big_decimal_number
pry(main)> big_decimal_number = BigDecimal 123
=> 0.123e3
# convert the data to JSON
pry(main)> json_data = { float_number: float_number, big_decimal_number: big_decimal_number }.to_json
=> "{"float_number":123.0,"big_decimal_number":"123.0"}"
# parse JSON to variable parsed_json_data to check the data
pry(main)> parsed_json_data = JSON.parse json_data
=> {"float_number"=>123.0, "big_decimal_number"=>"123.0"}
# check the class of "float_number"
pry(main)> parsed_json_data["float_number"].class
=> Float
## check the class of "big_decimal_number"
pry(main)> parsed_json_data["big_decimal_number"].class
=> String
We can look at the example above in Rails Console, we created 2 data with different numeric type and converted to JSON and using .class
to check the the data type. Rails keeps float_number
as Float
but serializes BigDecimal
as String
.
How we can fix this?
There are 3 ways to fix this issue when you need BigDecimal in your JSON
- In Rails version before 4.1 we can add
ActiveSupport::JSON::Encoding.encode_big_decimal_as_string = false
to your rails application config(config/application.rb)
to disable rails serializes BigDecimal as String in JSON, but it has been deprecated in Rails 4.1. - For the Rails version above 4.1, We can use gem activesupport-json_encoder to achieve the same goal. This gem was extracted from the Rails framework (This gem not supported in Rails 5)
- You can monkey patching
as_json
inBigDecimal
class BigDecimal
def as_json
to_d
end
end
Conclusion
From this document we know that client may get the wrong number because most libraries parse non-integer JSON numbers directly as floats. Therefore the safest way is convert the data to String to keep the real value. However, you still can use the solutions above to convert your BigDecimal data to numeric in JSON.
The post Cautious when convert a BigDecimal value to JSON in Rails appeared first on CoinGecko Blog.