Search
Close this search box.

Cautious when convert a BigDecimal value to JSON in Rails

Blog-2-Ruby-on-Rails-2-1110x0-c-default

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

  1. 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.
  2. 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)
  3. You can monkey patching as_json in BigDecimal
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.

Twitter
Telegram
Facebook
LinkedIn
Email

10 thoughts on “Cautious when convert a BigDecimal value to JSON in Rails”

  1. Robert Harmon

    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

  2. JonathanNaylor

    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.

  3. 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…

  4. 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.

  5. 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.

Leave a Comment

Your email address will not be published. Required fields are marked *