-
-
Notifications
You must be signed in to change notification settings - Fork 250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Strange behavior serializing BigDecimal with JSON.generate #693
Comments
Sorry for the delay. When I load up rails and the JSON gem and call Without the changes to the defaults Oj behaves the same as both test cases. BigDecimals are output as strings. Setting the I know that doesn't solve you problem so maybe we can discuss other ways of getting what you want. One thought is not using the rails or compat modes. Is that possible? |
Hi, Peter. Thanks for your attention on this issue and also sorry for my late response. I understand that you can't change how Here is a small script that I used to test: require 'bundler/inline'
OJ_VERSION = '3.13.6'
puts "With OJ version (#{OJ_VERSION})"
gemfile do
source 'https://rubygems.org'
gem 'rails'
gem 'oj', OJ_VERSION
end
puts "Before optimizing"
puts "Load"
p JSON.load("{\"ticker\":\"ASAI3\",\"price\":\"18.7\",\"rate\":-0.8}")
p Oj.load("{\"ticker\":\"ASAI3\",\"price\":\"18.7\",\"rate\":-0.8}")
puts "Generate"
p JSON.generate({:ticker=>"ASAI3", :price=>18.7, :rate=>-0.8.to_d})
p Oj.generate({:ticker=>"ASAI3", :price=>18.7, :rate=>-0.8.to_d})
Oj.optimize_rails
Oj.default_options = {
mode: :rails,
bigdecimal_as_decimal: true,
bigdecimal_load: true
}
puts "After optimizing"
puts "Load"
p JSON.load("{\"ticker\":\"ASAI3\",\"price\":\"18.7\",\"rate\":-0.8}")
p Oj.load("{\"ticker\":\"ASAI3\",\"price\":\"18.7\",\"rate\":-0.8}")
puts "Generate"
p JSON.generate({:ticker=>"ASAI3", :price=>18.7, :rate=>-0.8.to_d})
p Oj.generate({:ticker=>"ASAI3", :price=>18.7, :rate=>-0.8.to_d}) Results when running with v3.11.3:
Results when running with latest (v3.13.6):
When using the latest version If you need any more information just let me know. |
The question to ask if you are using Oj mimicking the JSON gem is whether the JSON gem has that option. Since it does not it will not be honored. The http://www.ohler.com/oj/doc/file.Modes.html shows what is supported in each mode. I just noticed yard didn't generate the table correctly. I'll clean that up tonight. |
Table should look okay now. I really can't support a deviation from the JSON gem behaviour for the :compat and :rails modes as there will be others that complain for that deviation. My best suggestion is to use :custom mode so you can tune Oj to what you want. |
Thanks for your answer, there's just one thing that I don't quite
understand, and probably I'm just having the wrong assumption here, as
this modes and compatibility between Oj, Rails and JSON seems quite
complex.
Reading the docs and the modes table I understand that in rails mode, if
the option bigdecimal_as_decimal is set to true then it would output
those values as numbers and not string, as it is pointed out in footnote
3. So, why is this not happening in the examples I've shown above? Where
the values are still strings. Are the docs incorrect? Is this really a
different behavior? Or did I just not really understood what those modes
and options are doing?
I'll try to use the custom mode and see how it does on our use case, I
just wanted to understand why the option is not doing what I assumed it
should do, maybe we can improve the docs and I can always help with a PR
or something.
Thanks for your attention and have a nice weekend.
On September 17, 2021, Github ***@***.***> wrote:
Table should look okay now. I really can't support a deviation from
the JSON gem behaviour for the :compat and :rails modes as there will
be others that complain for that deviation. My best suggestion is to
use :custom mode so you can tune Oj to what you want.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#693 (comment)>, or
unsubscribe <https://github.com/notifications/unsubscribe-
auth/AABUBSIQF276L6ABGX5JIITUCPGYPANCNFSM5CCCQHIA>.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-
email&mt=8&pt=524675> or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-
email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
Sadly the interaction between the JSON gem and Rails is extremely complex and inconsistent. You might notice that a very high percentage of issues are around getting the Oj behaviour to match under different situations. As for the rails mode, rails also has the active support generator and it monkey patches the same types that the JSON gem does. If you find a combination where Oj is different than either rails or the JSON gem I'll take a look. Sure hope you don't though. There are so many special cases as it is. |
The option `:bigdecimal_as_decimal` is not available in Rails Mode (as discussed here ohler55#693), as the original JSON and Rails implementation does not have a way to "force" bigdecimal values to be encoded as numbers in json.
* Update usage of :bigdecimal_as_decimal in Rails Mode The option `:bigdecimal_as_decimal` is not available in Rails Mode (as discussed here #693), as the original JSON and Rails implementation does not have a way to "force" bigdecimal values to be encoded as numbers in json. * Update docs for :bigdecimal_as_decimal in Rails Mode * Use a more welcoming message
Hi @ohler55, thanks for your amazing work on Oj! I found an "issue" in the way
BigDecimal
is handled when upgrading from v3.11.3 to v3.11.4 when usingJSON.generate
.It's a rails project with using those configs:
When using v3.11.3:
BigDecimal
values are converted to numerical values.When using v3.11.4:
In this case,
BigDecimal
values are being converted to string values whenJSON.generate
is used.I found this when some ActiveJobs (with Sidekiq as the queue adapter) started to fail, those jobs receive
BigDecimal
values and now those values are being processed asstring
when the job deserializes the arguments. As far as I could debug it seems like Sidekiq usesJSON.generate
when pushing the job data to the Redis database, thus creating inconsistency.The issue seems to be introduced on v3.11.4, but is still present on the latest release (3.13.0 atm).
Let me know if you need more information.
The text was updated successfully, but these errors were encountered: