2015-06-03 2 views
2

Добрые господа. Как я могу заставить request.body (или любую другую строку, отличную от JSON) распечатать в приятном многослойном стиле JSON или yaml?Как получить красивую печать из строки, закодированной в форме

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

def request_token_from_google 
    uri = URI.parse('https://www.googleapis.com/oauth2/v3/token') 
    http = Net::HTTP.new(uri.host, uri.port) 
    http.use_ssl = true 
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE 
    request = Net::HTTP::Post.new(uri.request_uri) 
    request.set_form_data(self.to_params) 
    puts "request body is" 
    puts request.body.to_yaml # doesn't work 
    puts request.body.to_json # doesn't work 
    http.request(request) 
    end 
+0

'request.body' это просто форма-кодированный string, например 'foo = 1 & bar = 2 & ...'. Можете ли вы изменить свой вопрос, чтобы дать нам пример того, как вы хотите, чтобы результат выглядел? –

+0

Спасибо. Переформулировал вопрос, основанный на этом новом прозрении. – dwilbank

+0

Я не совсем понимаю, что вы делаете, но я предлагаю вам установить [pry rails] (https://github.com/rweng/pry-rails) и посмотреть, не решит ли ваша проблема. Это своего рода бросок в темное предложение, но pry rails - это мой инструмент для всего, что угодно. – crowhill

ответ

2

Проблема с этим:

ap "request body is #{request.body.to_json}" 

... и другие ваши попытки в том, что вы пытаетесь довольно-печать то, что это уже строка. Цель awesome_print (и inspect и их ilk) - взять объект, который имеет некоторую структуру и напечатать его так, чтобы вы могли видеть его структуру, но строка не имеет структуры - это просто символ, символ, символ. Когда вы даете awesome_print строку вроде "request body is {"foo":..., она не знает, что что-то особенное в части после «есть».

Если у вас объект со структурой, решение было бы дать ему непосредственно awesome_print:

puts "request body is:" 
ap my_hash_or_array 

К сожалению, в данном случае это не поможет, потому что request.body это просто строка, слишком- это форма-кодированные данные, как это (похищенные из Wikipedia):

Name=Jonathan+Doe&Age=23&Formula=a+%2B+b+%3D%3D+13%25%21 

Так же, как "request body is..." например, awesome_print не имеет возможности узнать, что это ничего особенного. Одна очень простая вещь, которую вы могли бы сделать, это просто поставить новую строку между каждой парой ключ/значение:

body = "Name=Jonathan+Doe&Age=23&Formula=a+%2B+b+%3D%3D+13%25%21" 

puts "Request body is:" 
puts body.gsub("&", "\n &") 
# => Request body is: 
# Name=Jonathan+Doe 
#  &Age=23 
#  &Formula=a+%2B+b+%3D%3D+13%25%21 

Это имеет недостаток, что значения еще процентов кодированный, как вы можете видеть, в случае Formula. Если это проблема, вы можете проанализировать данные формы, используя CGI.parse или Rack::Utils.parse_query, оба из которых доступны в Rails. Они оба возвращают хеш, который вы можете дать awesome_print, но немного разные форматы (CGI возвращает все значения в виде массивов, Rack :: Utils, только если они находятся в формате «массив», например foo[]=1&foo[]=2). Вот Rack :: Utils (вы просто должны представить себе, что выход окрашена):

puts "Request body is:" 
ap Rack::Utils.parse_query(body) 
# => Request body is:" 
# { 
#   "Name" => "Jonathan Doe", 
#   "Age" => "23", 
#  "Formula" => "a + b == 13%!" 
# } 

Наконец, немного непрошеный совет: puts и ap, которые пишут в STDOUT, как правило, работают хорошо в развитии, потому что Регистратор Rails также записывает в STDOUT, поэтому вы видите вывод puts в том же окне терминала, что и журнал сервера Rails. Однако в производстве данные, записанные в STDOUT, не могут быть записаны в файл в любом месте, и даже если это произойдет, если вы измените конфигурацию Rails.logger в какой-то момент, вывод ap может все еще проходить в другом месте. Вероятно, вы хотите использовать рекордер Rails вместо puts или ap, так что вы можете быть уверены, что все ваши данные поступают на одно и то же место. К счастью, awesome_print добавляет awesome_inspect метод для каждого объекта, который возвращает ту же самую симпатичную строку, которую вы видите, когда вы используете ap, так что вы все еще можете использовать awesome_print с Rails.logger:

body_inspect = Rack::Utils.parse_query(body).awesome_inspect 
Rails.logger.info("Request body is:\n#{body_inspect}") 
+0

Спасибо. Попробуй этот parse_query скоро! – dwilbank

 Смежные вопросы

  • Нет связанных вопросов^_^