4

Using ActiveRecord::Base.to_json I do:

user = User.find_by_name 'Mika'

{"created_at":"2011-07-10T11:30:49+03:00","id":5,"is_deleted":null,"name":"Mika"}

Now, what I would like to have is:

{
    "created_at":"2011-07-10T11:30:49+03:00",
    "id":5,
    "is_deleted":null,
    "name":"Mika"
}

Is there an option to do this?

It would be great to have a global option, so that the behaviour be set depending on dev/live environment.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
mikabytes
  • 1,818
  • 2
  • 18
  • 30
  • 2
    Check out http://stackoverflow.com/questions/86653/how-can-i-pretty-format-my-json-output-in-ruby-on-rails – Thilo Jul 10 '11 at 09:29

2 Answers2

6

I'll go out on a limb and say "no, there is no such option".

AFAIK, the JSON encoding is actually handled by ActiveSupport rather than ActiveRecord. If you look at lib/active_support/json/encoding.rb for your ActiveSupport gem, you'll see a lot of monkey patching going on to add as_json and encode_json methods to some core classes; the as_json methods are just used to flatten things like Time, Regexp, etc. to simpler types such as String. The interesting monkey patches are the encode_json ones, those methods are doing the real work of producing JSON and there's nothing in them for controlling the final output format; the Hash version, for example, is just this:

# comments removed for clarity
def encode_json(encoder)
  "{#{map { |k,v| "#{encoder.encode(k.to_s)}:#{encoder.encode(v, false)}" } * ','}}"
end

The encoder just handles things like Unicode and quote escaping. As you can see, the encode_json is just mashing it all together in one compact string with no options for enabling prettiness.

All the complex classes appear to boil down to Hash or Array during JSONification so you could, in theory, add your own monkey patches to Hash and Array to make them produce something pretty. However, you might have some trouble keeping track of how deep in the structure you are so producing this:

{
    "created_at":"2011-07-10T11:30:49+03:00",
    "id":5,
    "is_deleted":null,
    "name":"Mika"
    "nested":{
    "not":"so pretty now",
    "is":"it"
}
}

Would be pretty straight forward but this:

{
    "created_at":"2011-07-10T11:30:49+03:00",
    "id":5,
    "is_deleted":null,
    "name":"Mika"
    "nested": {
        "not":"so pretty now",
        "is":"it"
    }
}

would be harder and, presumably, you'd want the latter and especially so with deeply nested JSON where eyeballing the structure is difficult. You might be able to hang a bit of state on the encoder that gets passed around but that would be getting a little ugly and brittle.

A more feasible option would be an output filter to parse and reformat the JSON before sending it off to the browser. You'd have to borrow or build the pretty printer but that shouldn't be that difficult. You should be able to conditionally attach said filter only for your development environment without too much ugliness as well.

If you're just looking to debug your JSON based interactions then maybe the JSONovich extension for Firefox would be less hassle. JSONovich has a few nice features (such as expanding and collapsing nested structures) that go beyond simple pretty printing too.


BTW, I reviewed Rails 3.0 and 3.1 for this, you can check Rails 2 if you're interested.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
  • Thank you mu for the detailed answer. For now I will take the "easy" escape of installing the addon in Firefox, and use Firebug's built-in JSON viewer for Ajax calls. On a side-note; I'm not using Rails. I'm building RESTful services with Sinatra and ActiveRecord as backend, and ExtJs for the frontend. Cheers! – mikabytes Jul 11 '11 at 12:09
1

Have you considered the JSON gem? I believe it does exactly what you're looking for.

e.g.

JSON.pretty_generate(user)

Have a look at the detail here...

http://apidock.com/ruby/JSON/pretty_generate

sands
  • 342
  • 3
  • 9
  • Wow, this is a very old question. Both the task and the company are long gone :) I've tried your solution which is producing nice results. Not sure how well it will fit into the monkeypatching done by ActiveRecord.. Probably wouldn't fit, but viable as a custom solution. – mikabytes Nov 20 '12 at 16:14