rails/rails — pull request #12862 by chancancode (2013-11-12 10:20:08+00:00)
Title: [WIP] JSON gem compatibility

This is extracted from #12183 as an isolated PR. I documented the current state of JSON-gem-vs-active-support incompatibility [here](https://github.com/intridea/multi_json/pull/138#issuecomment-24468223). Clearly, you cannot currently use the JSON gem's `dump` or `generate` method in conjunction with ActiveSupport's JSON encoder, otherwise, things may break unexpectedly on certain input at runtime with a cryptic error. This limitation is not currently very well known. It's probably safe to assume that the situation is going to get worse as we move to Ruby 1.9+ (where the JSON gem ships with the stdlib) and as multi_json is being EOL'ed and removed from Rails 4.1 (many gem authors simply replaced `MultiJson.dump` with `::JSON.{dump,generate}`.

To improve the situation, we can do one of the following things:

1. **Do nothing**: This feels irresponsible, especially when we know that this is going to fail in subtle and non-obvious way in seemingly (to the user) unpredictable manner.

2. **Document this behaviour and warn people about using JSON gem together with Rails**: this doesn't really help, who read documentations? In practice, this would have the same effect as 1.

3. **Boycott JSON gem, override `::JSON.{dump,generate}` to raise an exception when ActiveSupport::JSON is loaded**: while this might be ideal from a purist perspective, I'm afraid this is a non-starter – even some of our dependencies are currently using `::JSON.{dump,generate}` in their codebase.

4. **Make it possible for AS::JSON and JSON gem to coexist in peace**: this is what I propose to do. It seems like the only reasonable and responsible thing to do.

With this PR, calling `::JSON.{generate,dump}` will invoke the JSON gem's encoder. It will **not** invoke any of the `ActiveSupport::JSON` logic, i.e. it will bypass `as_json` and ignore any options that it does not natively understand (e.g. `only`, `except`, etc). Instead of using the ad-hoc approach in #9295, this PR changes our version of `to_json` to add some triage code. The end result is that invoking `::JSON.{generate,dump}` will yield the same result before and after `ActiveSupport::JSON` is loaded.

If I get a :+1: from core, I'll can clean things up, add the changelog, etc.

cc @jeremy