views:

35

answers:

1

Rails 2.3.6 started using the fast new json library, yajl-ruby, "if available".

In the "JSON gem Compatibility API" section of the yajl-ruby readme it outlines a method to just drop in yajl-ruby inclusion and have the rest of the app seamlessly pick it up.

So, ideally, I'd like

  1. Rails to use it
  2. My gems to use it
  3. My application code to use it

What's the easiest way to achieve this? My guess:

config.gem 'yajl-ruby', :lib => 'yajl/json_gem'

As the very first gem in environment.rb. Doing this doesn't result in any errors, but I'm not sure how to know if rails is picking it up for its own use.

Thanks! John

+1  A: 

Hey John, I'd recommend using yajl-ruby's API directly instead of the JSON gem compatibility API mainly for the reason that the JSON gem's to_json method conflict with ActiveSupport and has had long-standing issues making them work together.

If you just do config.gem 'yajl-ruby', :lib => 'yajl' instead, you'll need to use Yajl::Parser and Yajl::Encoder directly to parse/encode objects. The advantage of this is you'll be certain there won't be any conflicts with method overrides and as such, be guaranteed your JSON encoding/parsing code will work as expected. The disadvantage is if you're using any gems that use the JSON gem, they'll continue to do so but you're own code will use yajl-ruby.

If you wanted to, you could use your config.gem line, then in an initializer require 'yajl' so you'd have both API's loaded. The yajl/json_gem include will override anything that's using the JSON gem with yajl - to ensure this overrides those methods try to make sure require 'yajl/json_gem' happens last.

If you're using Rails 3, you can add this to an initializer:

ActionController::Renderers.add :json do |json, options|
  json = Yajl.dump(json) unless json.respond_to?(:to_str)
  json = "#{options[:callback]}(#{json})" unless options[:callback].blank?
  self.content_type ||= Mime::JSON
  self.response_body  = json
end

To make sure render :json => ... calls use yajl-ruby as well.

Sorry if this isn't really answering your question but I wanted to at least give the suggestion of using yajl-ruby's API directly :)

Wow, thanks for a very comprehensive answer with a lot of options. But I actually think I still don't know how to achieve #1 in my list -- having rails notice yajl-ruby and use it. :)
John
As far as I know, if you have yajl-ruby loaded (and/or listed in your config.gem or bundler config) Rails 2.3.6+ will use it as it's default JSON backend for parsing.