with Como faço para analisar JSON com Ruby on Rails?




ruby json fast (11)

O pacote JSON do Ruby é capaz de exibir um pouco de magia por conta própria.

Se você tiver uma string contendo dados serializados JSON que deseja analisar:

JSON[string_to_parse]

O JSON examinará o parâmetro, verá que é uma String e tentará decodificá-lo.

Da mesma forma, se você tiver um hash ou matriz que deseja serializar, use:

JSON[array_of_values]

Ou:

JSON[hash_of_values]

E o JSON irá serializá-lo. Você também pode usar o método to_json se quiser evitar a semelhança visual do método [] .

aqui estão alguns exemplos:

hash_of_values = {'foo' => 1, 'bar' => 2}
array_of_values = [hash_of_values]

JSON[hash_of_values] 
# => "{\"foo\":1,\"bar\":2}"

JSON[array_of_values] 
# => "[{\"foo\":1,\"bar\":2}]"

string_to_parse = array_of_values.to_json
JSON[string_to_parse]
# => [{"foo"=>1, "bar"=>2}]

Se você torcer pelo JSON, poderá notar que é um subconjunto do YAML e, na verdade, o analisador YAML é o que está manipulando o JSON. Você também pode fazer isso:

require 'yaml'

YAML.load(string_to_parse)
# => [{"foo"=>1, "bar"=>2}]

Se seu aplicativo estiver analisando YAML e JSON, você poderá deixar o YAML lidar com os dois tipos de dados serializados.

Esta questão já tem uma resposta aqui:

Eu estou procurando uma maneira simples de analisar JSON, extrair um valor e gravá-lo em um banco de dados no Rails.

Especificamente, o que estou procurando é uma maneira de extrair o shortUrl do JSON retornado da API bit.ly:

{
  "errorCode": 0,
  "errorMessage": "",
  "results":
  {
    "http://www.foo.com":
    {
       "hash": "e5TEd",
       "shortKeywordUrl": "",
       "shortUrl": "http://bit.ly/1a0p8G",
       "userHash": "1a0p8G"
    }
  },
  "statusCode": "OK"
}

E, em seguida, pegue esse shortUrl e grave-o em um objeto ActiveRecord associado à URL longa.

Esta é uma daquelas coisas que eu posso pensar completamente em conceito e quando me sento para executar eu percebo que tenho muito a aprender.


Essa resposta é bem antiga. o pguardiario tem isso.

Um site para check-out é a implementação JSON para Ruby . Este site oferece uma jóia que você pode instalar para uma variante de extensão C muito mais rápida.

Com os benchmarks, dada a sua página de documentação, eles afirmam que é 21.500x mais rápido do que o ActiveSupport::JSON.decode

O código seria o mesmo que a resposta de Milan Novota com esta jóia, mas a análise seria apenas:

parsed_json = JSON(your_json_string)

Você pode tentar algo assim:

def details_to_json
{
  :id                    => self.id, 
  :credit_period_type    => self.credit_period_type,
  :credit_payment_period => self.credit_payment_period,

 }.to_json
end

Oj gem ( https://github.com/ohler55/oj ) deve funcionar. É simples e rápido.

http://www.ohler.com/oj/#Simple_JSON_Writing_and_Parsing_Example

require 'oj'

h = { 'one' => 1, 'array' => [ true, false ] }
json = Oj.dump(h)

# json =
# {
#   "one":1,
#   "array":[
#     true,
#     false
#   ]
# }

h2 = Oj.load(json)
puts "Same? #{h == h2}"
# true

A joia do Oj não funciona para o JRuby. Para o JRuby isso ( https://github.com/ralfstx/minimal-json ) ou isso ( https://github.com/clojure/data.json ) pode ser uma boa opção.


Isso pode ser feito como abaixo, só precisa usar JSON.parse , então você pode percorrê-lo normalmente com índices.

#ideally not really needed, but in case if JSON.parse is not identifiable in your module  
require 'json'

#Assuming data from bitly api is stored in json_data here

json_data = '{
  "errorCode": 0,
  "errorMessage": "",
  "results":
  {
    "http://www.foo.com":
    {
       "hash": "e5TEd",
       "shortKeywordUrl": "",
       "shortUrl": "http://whateverurl",
       "userHash": "1a0p8G"
    }
  },
  "statusCode": "OK"
}'

final_data = JSON.parse(json_data)
puts final_data["results"]["http://www.foo.com"]["shortUrl"]

Aqui está o que eu faria:

json = "{\"errorCode\":0,\"errorMessage\":\"\",\"results\":{\"http://www.foo.com\":{\"hash\":\"e5TEd\",\"shortKeywordUrl\":\"\",\"shortUrl\":\"http://b.i.t.ly/1a0p8G\",\"userHash\":\"1a0p8G\"}},\"statusCode\":\"OK\"}"

hash = JSON.parse(json)
results = hash[:results]

Se você souber o URL de origem, poderá usar:

source_url = "http://www.foo.com".to_sym

results.fetch(source_url)[:shortUrl]
=> "http://b.i.t.ly/1a0p8G"

Se você não souber a chave do URL de origem, poderá fazer o seguinte:

results.fetch(results.keys[0])[:shortUrl]
=> "http://b.i.t.ly/1a0p8G"

Se você não quiser pesquisar chaves usando símbolos, poderá converter as chaves do hash em strings:

results = json[:results].stringify_keys

results.fetch(results.keys[0])["shortUrl"]
=> "http://b.i.t.ly/1a0p8G"

Se você acha que a estrutura JSON pode mudar, você pode criar um esquema JSON simples e validar o JSON antes de tentar acessar as chaves. Isso forneceria um guarda.

NOTA: teve que mangle o bit.ly url por causa das regras de postagem.


Aqui está uma atualização para 2013.

Rubi

O Ruby 1.9 tem uma gem JSON padrão com extensões C. Você pode usá-lo com

require 'json'
JSON.parse ''{ "x": "y" }'
# => {"x"=>"y"}

A parse! variante pode ser usada para fontes seguras . Há também outras gemas, que podem ser mais rápidas que a implementação padrão. Por favor, consulte multi_json para a lista.

Trilhos

As versões modernas do Rails usam multi_json , uma gem que usa automaticamente a gem JSON mais rápida disponível. Assim, a maneira recomendada é usar

object = ActiveSupport::JSON.decode json_string

Por favor, consulte o ActiveSupport::JSON para mais informações. Em particular, a linha importante na fonte do método é

data = MultiJson.load(json, options)

Em seguida, no seu Gemfile, inclua as gemas que você deseja usar. Por exemplo,

group :production do
  gem 'oj'
end

Essas respostas são um pouco datadas. Por isso eu te dou:

hash = JSON.parse string

O Rails deve carregar automaticamente o módulo json para você, então você não precisa adicionar require 'json' .


Ruby tem um analisador JSON:

require 'json'

RUBY é sensível a maiúsculas e minúsculas.

require 'json' # json must be lower case

JSON.parse(<json object>)  

por exemplo

JSON.parse(response.body) # JSON must be all upper-case

require 'json'

hash = JSON.parse string

trabalhe com o hash e faça o que você quer fazer.





json