我希望我在Ruby on Rails中的JSON输出“漂亮”或格式化得很好。

现在,我调用to_json,我的JSON都在一行上。有时,很难看出JSON输出流中是否有问题。

有办法配置,使我的JSON“漂亮”或很好的格式在Rails?


当前回答

下面是根据@gertas的回答修改的中间件解决方案。这个解决方案不是Rails特有的——它应该适用于任何Rack应用程序。

这里使用的中间件技术,使用#each,由Eifion Bedford在ASCIIcasts 151: Rack middleware中进行了解释。

这段代码放在app/middleware/pretty_json_response.rb中:

class PrettyJsonResponse

  def initialize(app)
    @app = app
  end

  def call(env)
    @status, @headers, @response = @app.call(env)
    [@status, @headers, self]
  end

  def each(&block)
    @response.each do |body|
      if @headers["Content-Type"] =~ /^application\/json/
        body = pretty_print(body)
      end
      block.call(body)
    end
  end

  private

  def pretty_print(json)
    obj = JSON.parse(json)  
    JSON.pretty_unparse(obj)
  end

end

要打开它,将其添加到config/environments/test中。config/environments/development.rb:

config.middleware.use "PrettyJsonResponse"

正如@gertas在他的解决方案版本中警告的那样,避免在生产中使用它。有点慢。

使用Rails 4.1.6测试。

其他回答

看看Awesome Print吧。将JSON字符串解析为Ruby Hash,然后用ap显示它,如下所示:

require "awesome_print"
require "json"

json = '{"holy": ["nested", "json"], "batman!": {"a": 1, "b": 2}}'

ap(JSON.parse(json))

通过以上,你会看到:

{
  "holy" => [
    [0] "nested",
    [1] "json"
  ],
  "batman!" => {
    "a" => 1,
    "b" => 2
  }
}

Awesome Print还会添加一些Stack Overflow无法显示的颜色。

如果您希望在Rails控制器动作中快速实现此功能以发送JSON响应:

def index
  my_json = '{ "key": "value" }'
  render json: JSON.pretty_generate( JSON.parse my_json )
end

我使用了宝石CodeRay,它工作得很好。格式包括颜色,它可以识别很多不同的格式。

我已经在一个可以用来调试rails api的gem上使用了它,它工作得非常好。

顺便说一下,这个gem被命名为'api_explorer' (http://www.github.com/toptierlabs/api_explorer)

多亏了机架中间件和Rails 3,你可以为每个请求输出漂亮的JSON,而无需更改应用程序的任何控制器。我已经编写了这样的中间件片段,我在浏览器和curl输出中得到了漂亮的打印JSON。

class PrettyJsonResponse
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, response = @app.call(env)
    if headers["Content-Type"] =~ /^application\/json/
      obj = JSON.parse(response.body)
      pretty_str = JSON.pretty_unparse(obj)
      response = [pretty_str]
      headers["Content-Length"] = pretty_str.bytesize.to_s
    end
    [status, headers, response]
  end
end

上面的代码应该放在app/middleware/pretty_json_response中。您的Rails项目的rb。 最后一步是在config/environments/development.rb中注册中间件:

config.middleware.use PrettyJsonResponse

我不建议在生产中使用它。JSON的重新解析可能会降低你的产品应用的响应时间和吞吐量。最终,额外的逻辑,如'X-Pretty-Json: true'头可能会被引入,以触发手动curl请求按需格式化。

(在Rails 3.2.8-5.0.0, Ruby 1.9.3-2.2.0, Linux下测试)

如果你正在使用RABL,你可以使用JSON.pretty_generate来配置它:

class PrettyJson
  def self.dump(object)
    JSON.pretty_generate(object, {:indent => "  "})
  end
end

Rabl.configure do |config|
  ...
  config.json_engine = PrettyJson if Rails.env.development?
  ...
end

使用JSON的一个问题。pretty_generate是JSON模式验证器将不再满意您的datetime字符串。你可以在config/initializers/rabl_config中修正这些问题。rb:

ActiveSupport::TimeWithZone.class_eval do
  alias_method :orig_to_s, :to_s
  def to_s(format = :default)
    format == :default ? iso8601 : orig_to_s(format)
  end
end