I am stumped with this problem.
ActiveSupport::JSON defines to_json on various core objects and so does the JSON gem. However, the implementation is not the same — the ActiveSupport version takes arguments and the JSON gem version doesn’t.
I installed a gem that required the JSON gem and my app broke. The issue is that I’m using to_json in a controller that returns a list of objects, but I want to control which attributes are returned.
When code anywhere in my system does require 'json' I get this error message:
TypeError: wrong argument type Hash (expected Data)
I tried a couple of things that I read online to fix it, but nothing worked. I ended up re-writing the gem to use ActiveSupport::JSON.decode instead of JSON.parse.
This works but it’s not sustainable…I can’t be forking gems every time I want to use a gem that requires the JSON gem.
Update: The best solution of this problem is to upgrade to Rails 2.3 or higher, which fixed it.
Update This fix is only applicable to Rails < 2.3. As Giles mentions below, they fixed this in 2.3 internally using much the same technique. But beware the json gem’s earlier attempt at Rails compatibility (
json/add/rails), which, if required explicitly will break everything all over again.Do you mean the
require 'json'statement itself raises that Exception? Or do you mean when you call@something.to_json(:something => value)you get the error? The latter is what I would expect, if you have a problem requiring the JSON gem then I’m not sure what’s going on.I just ran into this problem with the oauth gem. In my case, there is not a true conflict, because the oauth gem doesn’t depend on
to_jsonimplementation. Therefore the problem is that JSON is clobbering the ActiveSupport declarations. I solved this by simply requiring json before ActiveSupport is loaded. Puttinginside the
Rails::Initializerdid the trick (though putting it after the block did NOT).That allows ActiveSupport to clobber the default JSON implementation instead.
Now if you are using a gem that actually depends on the JSON implementation of
to_jsonthen you are up a creek. This is definitely the worst of meta-programming, and I would advocate for the Rails and JSON gem developers to resolve the conflict, though it will be painful because one or the other will have to break backwards compatibility.In the short term, gem authors may be able to bridge the gap by supporting both implementations. This is more or less feasible depending on how the gem uses the method. A worst case scenario is an official fork (ie.
gemandgem-rails).