Automating JSON evaluation in Rails

As I’m sure many of you already know, Prototype (Rails’ JavaScript framework) will automatically eval() JSON from Ajax responses if you pass it in the X-JSON header. It even says so right here. The Rails team don’t want to automate this on the server side as recent versions of Prototype are moving away from this approach in favour of evalJSON(), as described in the Prototype docs. Still, the latest release of Rails ships with Prototype 1.5.0, so I figured this was still useful.

Just throw this in a file in your lib directory and remember to require it in config/environment.rb (line wraps marked »):

module ActionController
  class Base
  protected
    def render_json_with_xjson_header(json, »
        callback = nil, status = nil)
      headers['X-JSON'] = json
      render_json_without_xjson_header(json, callback, status)
    end
    alias_method(:render_json_without_xjson_header, :render_json)
    alias_method(:render_json, :render_json_with_xjson_header)
  end
end

Now all your render :json calls will set the X-JSON header automatically.

Personally, I like 1.5.0’s way of doing things – I think it’s more elegant syntactically. Compare the Old Way:

new Ajax.Request( ... {
  onSuccess: function(request, json) {
    // Handle response
  }
});

with the New Way:

new Ajax.Request( ... {
  onSuccess: function(request) {
    var json = request.responseText.evalJSON();
    // Handle response
  }
});

For the time being, I think you can still use the Old Way with 1.5.1, but I’m not sure how long it’ll stick around.

If you’ve enjoyed this article, you might enjoy my recently published book JavaScript Testing Recipes. It’s full of simple techniques for writing modular, maintainable JavaScript apps in the browser and on the server.