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

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

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


当前回答

我在rails控制台中有一个JSON对象,并希望在控制台中很好地显示它(而不是像大量连接的字符串那样显示),它简单如:

data.as_json

其他回答

以下是我在搜索过程中从其他帖子中得到的解决方案。

这允许您根据需要将pp和jj输出发送到文件中。

require "pp"
require "json"

class File
  def pp(*objs)
    objs.each {|obj|
      PP.pp(obj, self)
    }
    objs.size <= 1 ? objs.first : objs
  end
  def jj(*objs)
    objs.each {|obj|
      obj = JSON.parse(obj.to_json)
      self.puts JSON.pretty_generate(obj)
    }
    objs.size <= 1 ? objs.first : objs
  end
end

test_object = { :name => { first: "Christopher", last: "Mullins" }, :grades => [ "English" => "B+", "Algebra" => "A+" ] }

test_json_object = JSON.parse(test_object.to_json)

File.open("log/object_dump.txt", "w") do |file|
  file.pp(test_object)
end

File.open("log/json_dump.txt", "w") do |file|
  file.jj(test_json_object)
end

下面是根据@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测试。

漂亮的打印变体(Rails):

my_obj = {
  'array' => [1, 2, 3, { "sample" => "hash"}, 44455, 677778, nil ],
  foo: "bar", rrr: {"pid": 63, "state with nil and \"nil\"": false},
  wwww: 'w' * 74
}
require 'pp'
puts my_obj.as_json.pretty_inspect.
            gsub('=>', ': ').
            gsub(/"(?:[^"\\]|\\.)*"|\bnil\b/) {|m| m == 'nil' ? 'null' : m }.
            gsub(/\s+$/, "")

结果:

{"array": [1, 2, 3, {"sample": "hash"}, 44455, 677778, null],
 "foo": "bar",
 "rrr": {"pid": 63, "state with nil and \"nil\"": false},
 "wwww":
  "wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww"}

使用pretty_generate()函数,该函数内置于JSON的后期版本中。例如:

require 'json'
my_object = { :array => [1, 2, 3, { :sample => "hash"} ], :foo => "bar" }
puts JSON.pretty_generate(my_object)

这就得到了:

{
  "array": [
    1,
    2,
    3,
    {
      "sample": "hash"
    }
  ],
  "foo": "bar"
}

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

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