6

Anyone have a way to pretty print JSON output from jbuilder?

I can pretty print JSON generated within a controller action with something like:

JSON.pretty_generate(some_json_object) 

but once I pass off to a jbuilder template, I'm not aware of a way to have that output pretty printed.

Right now, my action method's render statement is simple:

render formats: :json    

And this successfully forces a rendering with jbuilder, regardless of input format type specified (which is my desired behavior).

idStar
  • 10,674
  • 9
  • 54
  • 57

6 Answers6

6

I found a way to do this:

 json_string = render_to_string formats: :json    
 json_object = JSON.parse(json_string)     
 render :json => JSON.pretty_generate(json_object)     

Again, this assumes there is a jbuilder template for this action, which will create the initial json, which gets rendered to a string, back into a json object and then passed to pretty_generate().

It's a bit circuitous, but it works. I'm of course, totally open to tighter implementations!

idStar
  • 10,674
  • 9
  • 54
  • 57
6
# config/initializers/jbuilder_prettify.rb
require "jbuilder"

class Jbuilder
  ##
  # Allows you to set @prettify manually in your .jbuilder files. 
  # Example: 
  #   json.prettify true
  #   json.prettify false 
  #  
  attr_accessor :prettify

  alias_method :_original_target, :target!

  ##
  # A shortcut to enabling prettify.
  # Example:
  #   json.prettify!
  #
  def prettify!
    @prettify = true
  end

  def target!
    @prettify ? ::JSON.pretty_generate(@attributes) : _original_target
  end
end

# app/views/api/v1/users/show.json.jbuilder
json.prettify! if %w(1 yes true).include?(params["pretty"])

json.( @user, :id, :name, :created_at, :updated_at )

https://github.com/rails/jbuilder/issues/195#issuecomment-44440569

Mark Murphy
  • 2,834
  • 1
  • 31
  • 29
4

Expanding on Blake Miller's answer...

Here is the code from the gist:

require 'multi_json'
MultiJson.use :yajl
unless Rails.env.production?
  MultiJson.dump_options = {:pretty=>true}
end

I put this into a file called /config/initializers/jbuilder_prettify.rb

In order for this to work you must have the yajl-ruby gem included in your Gemfile. Note that the jbuilder github homepage mentions here how using something like yajl-ruby will speed up your json rendering.

DavB
  • 1,676
  • 2
  • 14
  • 16
1

This worked for me, while the accepted answer did not. It's also shorter!

https://gist.github.com/jmoe/02c7476adac24eddd969

require 'multi_json'
MultiJson.use :yajl
unless Rails.env.production?
  MultiJson.dump_options = {:pretty=>true}
end
Dathan
  • 7,266
  • 3
  • 27
  • 46
Blake Miller
  • 805
  • 11
  • 16
1

config/initializers/jbuilder.rb with:

class Jbuilder
  def target!
    ::JSON.pretty_generate(@attributes)
  end
end

Result, https://localhost:3000/manifest.json

{
  "name": "Socializus",
  "short_name": "Socializus",
  "start_url": "http://localhost:3000",
  "theme_color": "#ffffff",
  "background_color": "#ffffff",
  "display": "standalone",
  "icons": [
    {
      "src": "/android-chrome-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/android-chrome-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}
Dorian
  • 7,749
  • 4
  • 38
  • 57
-1

I think this is simpler,

@package = Package.first

json = JSON.parse(@blog.to_json)

PP.pp(json)

{"id_to_s"=>"5222675dbc11149e3a000002",
 "title"=>"Package Title",
 "version"=>"0.1.1",
 "comment"=>
  {"user"=>"Joe",
   "description"=>"Joe's comment"},
 "assets"=>
  [{"id_to_s"=>"522a4620fa451436f4000001",
    "_type"=>"Illustration",
    "start"=>0,
    "stop"=>100,
    "caption"=>"mountain climbing"},
   {"id_to_s"=>"522a56a6fa4514523a000001",
    "_type"=>"Illustration",
    "start"=>200,
    "stop"=>300,
    "caption"=>"airport"},
   {"id_to_s"=>"522a6a0ffa4514a30e000002",
    "_type"=>"Illustration",
    "start"=>400,
    "stop"=>600,
    "caption"=>"doc"},
   {"id_to_s"=>"522aa46bbc1114551f000001",
    "_type"=>"Illustration",
    "start"=>nil,
    "stop"=>nil,
    "caption"=>nil},
   {"id_to_s"=>"522aa47fbc1114551f000002",
    "_type"=>"Illustration",
    "start"=>10,
    "stop"=>30,
    "caption"=>"asdflkjsd"}]}

Or, the quicker one-liner,

PP.pp JSON.parse Blog.first.to_json
westonplatter
  • 1,475
  • 2
  • 19
  • 30
  • Agreed, this is much cleaner than the workaround I originally used. – idStar Sep 07 '13 at 07:53
  • 1
    Yep, and there's probably nine other ways to accomplish the same task. – westonplatter Sep 08 '13 at 04:38
  • Awesome dude. I know this comment isn't any informative the way community wants it to be. However, I am keen to know know of any links that I can do some short-cut magic on terminal related to rails? – RajG Dec 20 '13 at 17:22
  • 1
    This doesn't seem like it actually answers the question. This pretty-prints a Ruby Hash, which isn't valid JSON. If the goal is to return pretty-printed JSON from a controller action, this won't do the trick. – Dathan Mar 08 '17 at 18:48