How to Deal with the Conflict Between Activesupport::JSON and the JSON Gem

How do you deal with the conflict between ActiveSupport::JSON and the JSON gem?

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_json implementation. Therefore the problem is that JSON is clobbering the ActiveSupport declarations. I solved this by simply requiring json before ActiveSupport is loaded. Putting

require 'json'

inside the Rails::Initializer did 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_json then 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. gem and gem-rails).

How to resolve bundler gem version conflict with json gem

The json requirement has two parts. The first is >= 1.7.7 meaning the Gem must be greater than or equal to 1.7.7. 2.0.2 is, in fact, greater than 1.7.7, so you satisfy that requirement. However, the second part of that is that it must also be ~> 1.7 (pronounced "tiddle-wakka") is what's called a Pessimistic Constraint. It required that the first elements of the version number match but the last can be greater than or equal to the number given. So, for example, 1.7.0 would satisfy the constraint. As would 1.7.9 or 1.9.9, or even 1.423.8. However, 2.0.0 would fail that constraint because the major version number doesn't match the given value of "1".

Does to_json require parameters? what about within rails?

to_json does not require parameters, when you're using the version provided within rails (ActiveSupport::JSON) So that error message shows that it must be trying to call the to_josn method defined in the json gem.

So my actual source of confusion was around the way rails loads these libraries.

It will load the json gem and use it within a controller, even if I don't have a line saying 'require json' because rails loads gems as defined in environment.rb, so in fact I needed to remove the line

config.gem "json", :version=> '1.1.7'

...from my environment.rb . My code had been broken since I had added that. Confusingly I do need that gem, but only for scripting I'm doing outside of rails.

How to resolve a gem dependency conflict after installing email_spec

This happens because the Gem specifies an older version of MiniTest in its dependencies, and you have a newer version installed on your system.

Using bundle exec is the correct way. Please see the below:

When running an executable, ALWAYS use bundle exec [command]. Quoting from the bundler documentation: In some cases, running executables without bundle exec may work, if the executable happens to be installed in your system and does not pull in any gems that conflict with your bundle. However, this is unreliable and is the source of considerable pain.

http://yehudakatz.com/2011/05/30/gem-versioning-and-bundler-doing-it-right/

Bug in ruby JSON lib when handling 4-byte Unicode emoji?

There was a conflict between ActiveRecord and the standard JSON to_json method. The ActiveRecord to_json implementation had a bug. I solved it using the initializer specified in this thread:

How do you deal with the conflict between ActiveSupport::JSON and the JSON gem?

JSON encoding wrongly escaped (Rails 3, Ruby 1.9.2)

If you dig through the source you'll eventually come to ActiveSupport::JSON::Encoding and the escape method:

def escape(string)
if string.respond_to?(:force_encoding)
string = string.encode(::Encoding::UTF_8, :undef => :replace).force_encoding(::Encoding::BINARY)
end
json = string.
gsub(escape_regex) { |s| ESCAPED_CHARS[s] }.
gsub(/([\xC0-\xDF][\x80-\xBF]|
[\xE0-\xEF][\x80-\xBF]{2}|
[\xF0-\xF7][\x80-\xBF]{3})+/nx) { |s|
s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/n, '\\\\u\&')
}
json = %("#{json}")
json.force_encoding(::Encoding::UTF_8) if json.respond_to?(:force_encoding)
json
end

The various gsub calls are forcing non-ASCII UTF-8 to the \uXXXX notation that you're seeing. Hex encoded UTF-8 should be acceptable to anything that processes JSON but you could always post-process the JSON (or monkey patch in a modified JSON escaper) to convert the \uXXXX notation to raw UTF-8 if necessary.

I'd agree that forcing JSON to be 7bit-clean is a bit bogus but there you go.

Short answer: no.



Related Topics



Leave a reply



Submit