Как я могу "красиво" отформатировать вывод JSON в Ruby on Rails? - PullRequest
576 голосов
/ 17 сентября 2008

Я бы хотел, чтобы мой вывод JSON в Ruby on Rails был "красивым" или красиво отформатированным.

Прямо сейчас я звоню to_json, и мой JSON находится на одной строке. Иногда бывает трудно увидеть, есть ли проблема в потоке вывода JSON.

Есть ли способ настроить или метод сделать мой JSON "красивым" или красиво отформатированным в Rails?

Ответы [ 17 ]

2 голосов
/ 23 декабря 2012

Вот мое решение, которое я извлек из других постов во время собственного поиска.

Это позволяет отправлять вывод 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
2 голосов
/ 22 ноября 2013

Я использовал гем CodeRay, и он работает довольно хорошо. Формат включает цвета и распознает множество различных форматов.

Я использовал его на геме, который можно использовать для отладки API рельсов, и он работает довольно хорошо.

Кстати, самоцвет называется 'api_explorer' (http://www.github.com/toptierlabs/api_explorer)

2 голосов
/ 17 февраля 2016

Если вы хотите быстро реализовать это в действии контроллера Rails для отправки ответа JSON:

def index
  my_json = '{ "key": "value" }'
  render json: JSON.pretty_generate( JSON.parse my_json )
end
1 голос
/ 30 ноября 2015

# example of use:
a_hash = {user_info: {type: "query_service", e_mail: "my@email.com", phone: "+79876543322"}, cars_makers: ["bmw", "mitsubishi"], car_models: [bmw: {model: "1er", year_mfc: 2006}, mitsubishi: {model: "pajero", year_mfc: 1997}]}
pretty_html = a_hash.pretty_html

# include this module to your libs:
module MyPrettyPrint
    def pretty_html indent = 0
        result = ""
        if self.class == Hash
            self.each do |key, value|
                result += "#{key}</p>: #{[Array, Hash].include?(value.class) ? value.pretty_html(indent+1) : value}</p></li>"
            end
        elsif self.class == Array
            result = "[#{self.join(', ')}]"
        end
        "#{result}"
    end

end

class Hash
    include MyPrettyPrint
end

class Array
    include MyPrettyPrint
end
1 голос
/ 04 сентября 2015

Если вы используете 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 больше не будут удовлетворены вашими строками даты и времени. Вы можете исправить это в вашем 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
1 голос
/ 01 апреля 2014

Я использую следующее, поскольку нахожу заголовки, статус и вывод JSON полезными как множество. Процедура вызова нарушена по рекомендации из презентации на Railscasts: http://railscasts.com/episodes/151-rack-middleware?autoplay=true

  class LogJson

  def initialize(app)
    @app = app
  end

  def call(env)
    dup._call(env)
  end

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

  def each(&block)
    if @headers["Content-Type"] =~ /^application\/json/
      obj = JSON.parse(@response.body)
      pretty_str = JSON.pretty_unparse(obj)
      @headers["Content-Length"] = Rack::Utils.bytesize(pretty_str).to_s
      Rails.logger.info ("HTTP Headers:  #{ @headers } ")
      Rails.logger.info ("HTTP Status:  #{ @status } ")
      Rails.logger.info ("JSON Response:  #{ pretty_str} ")
    end

    @response.each(&block)
  end
  end
0 голосов
/ 23 мая 2019

Прекрасный вариант печати:

my_object = { :array => [1, 2, 3, { :sample => "hash"}, 44455, 677778, 9900 ], :foo => "bar", rrr: {"pid": 63, "state": false}}
puts my_object.as_json.pretty_inspect.gsub('=>', ': ')

Результат:

{"array": [1, 2, 3, {"sample": "hash"}, 44455, 677778, 9900],
 "foo": "bar",
 "rrr": {"pid": 63, "state": false}}
...