proposal: add option to pretty-print in json renderer

My reading of the action_controller json renderer

add :json do |json, options| json = json.to_json(options) unless json.kind_of?(String)

is that options come from the options hash you pass to render – so, it’s a hash. But my reading of Hash#to_json is that the only argument it accepts is a JSON::State object, not a hash. I think that means you can’t do anything useful (like enabling pretty-print) by passing options to the action_controller json renderer (passing indent: ' ' doesn’t work, for instance).

Given that, I’m proposing changing the :json renderer to something more like this:

  • config_accessor :default_json_pretty
  • self.default_json_pretty = false if default_json_pretty.nil?

add :json do |json, options|

  •  json = json.to_json(options) unless json.kind_of?(String)
    
  •  unless json.kind_of?(String)
    
  •    pretty = false
    
  •    pretty = options[:pretty] unless options[:pretty].nil?
    
  •    pretty = default_json_pretty if pretty.nil?
    
  •    json = json.to_json(pretty ? JSON::PRETTY_STATE_PROTOTYPE : nil)
    
  •  end
    

This would let you specify an app-wide default for render json: .. pretty printing, but also let you specify it (and override the default) for any given render call (with render json: .., pretty: false). And since to_json(options) already seems to be ignoring non-JSON::State arguments, it shouldn’t hurt to not pass them into it anymore.

Did I miss or missunderstand anything in the above? Does this sound like a good idea that I should work up?

Thanks!

Gabriel

In Rails 5.1 you will be able to change how the JSON is serialized. See https://github.com/rails/rails/pull/21496.