Rails 4.1 and JSON encoder
- Matthijs Langenberg
- 2014-09-26 @ 19:35
I might be late to the party, but I just upgraded a Rails app from 4.0 to
4.1, and I stumbled upon a change that might be interesting to other
The Rails guides inform about changes in JSON handling:
"Rails 4.1 fixed these issues by isolating its own encoder from the JSON
Sidekiq uses the JSON gem under the hood. I believe that Rails 4.0
overrides certain methods in such way, that Rails-specific features such as
#as_json are called. When you use Rails 4.1, that is no longer the case.
So when you pass arguments to Worker.perform_async, those arguments may be
serialized in a different way to Worker#perform then you expected before.
To give you a concrete example, the app I work on passes a hash containing
dates (actually ActiveSupport::TimeWithZone instances).
With Rails 4.0 these are passed to Worker#perform in ISO8601 format,
because of ActiveSupport::TimeWithZone#as_json.
With Rails 4.1 they are actually normal stringified dates:
gem 'rails', '4.0.10'
gem 'json', '1.8.1'
puts "Rails-" + Rails.version
Time.zone = 'Amsterdam'
time = Time.zone.now
# ["2014-09-26 21:01:51 +0200"] !! Broke one of my unit tests.
This might explain it even better:
My current solution is to call #as_json before calling
Worker.perform_async. So Worker.perform_async(args.as_json).
What do you think?