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.
10 thoughts on “Cautious when convert a BigDecimal value to JSON in Rails”
Hurry up!Don’t miss this offer.TronLink and Trust Wallet app 2021 has been officially released 300,000,000 TRON. Now the bounty program has begun again. Click here.
https://docs.google.com/forms/d/1eq82H1AS9M6c_cAMbr348s57dLEVDojq5RFvJzjl90w/edit
When you are converting a BigDecimal value to JSON, you need to initialize BigDecimal, it’s better to use “new BigDecimal” instead of “BigDecimal.new”. BigDecimal.new creates BigDecimal as Float, BigDecimal#new creates BigDecimal as BigDecimal, so you can do: json = BigDecimal.new(json) # instead of json = BigDecimal.new(json.to_s). Credit do my essay online
When working on my computer science dissertation, I was facing lots of issues during the conversion of BigDecimal value to JSON in Rails. However, the methods which you have shared here are quite easy and I am sure that I will be able to easily implement it.
you will feel that it is “unreasonably difficult” and just like that you are absorbed in the game Flappy Bird , you frantically plow the country in inhibitions and anger…
That should be `to_f` in the monkey-patch, not `to_d`.
I had a lot of problems converting words from letters BigDecimal values to JSON in Rails. I am confident that I will be able to simply implement the ideas you have presented here, though, as they are fairly simple.
The article is very interesting!
we offer our customers the most affordable prices in town. Panther Jackets is the place you wanna be. We deal with jackets of all types. We intend to provide our customers with the most premium quality jackets.
black varsity jacket
SOCVault is a security operations center as a service, SOC as a service, and SIEM as a service provider. SOCVault provides best-of-breed vendor solutions in one integrated platform to deliver the best security operations center experience to its customers. We have developed this unique solution on four pillars – Security Operations Center, Security Information and Event Management, Threat Intelligence, and Security Analytics.