pruebas - ¿Cómo puedo analizar JSON con Ruby on Rails?
rails web service json (13)
Aquí hay una actualización para el 2013.
Rubí
Ruby 1.9 tiene una gema de JSON predeterminada con extensiones C. Puedes usarlo con
require ''json''
JSON.parse ''''{ "x": "y" }''
# => {"x"=>"y"}
El parse!
La variante se puede utilizar para fuentes seguras . También hay otras gemas, que pueden ser más rápidas que la implementación predeterminada. Por favor, consulte multi_json para la lista.
Rieles
Las versiones modernas de Rails usan multi_json , una gema que utiliza automáticamente la gema JSON más rápida disponible. Por lo tanto, la forma recomendada es utilizar
object = ActiveSupport::JSON.decode json_string
Consulte ActiveSupport::JSON para obtener más información. En particular, la línea importante en la fuente del método es
data = MultiJson.load(json, options)
Luego, en tu Gemfile, incluye las gemas que quieras usar. Por ejemplo,
group :production do
gem ''oj''
end
Esta pregunta ya tiene una respuesta aquí:
- Analizando una cadena JSON en Ruby 7 respuestas
Estoy buscando una forma sencilla de analizar JSON, extraer un valor y escribirlo en una base de datos en Rails.
Específicamente, lo que estoy buscando es una forma de extraer shortUrl
del JSON devuelto desde la API bit.ly:
{
"errorCode": 0,
"errorMessage": "",
"results":
{
"http://www.foo.com":
{
"hash": "e5TEd",
"shortKeywordUrl": "",
"shortUrl": "http://bit.ly/1a0p8G",
"userHash": "1a0p8G"
}
},
"statusCode": "OK"
}
Y luego tome ese shortUrl y escríbalo en un objeto ActiveRecord asociado con la URL larga.
Esta es una de esas cosas en las que puedo pensar completamente en concepto y cuando me siento para ejecutar me doy cuenta de que tengo mucho que aprender.
El paquete JSON de Ruby es capaz de exhibir un poco de magia por sí solo.
Si tiene una cadena que contiene datos serializados JSON que desea analizar:
JSON[string_to_parse]
JSON verá el parámetro, verá que es una cadena e intentará descodificarlo.
De manera similar, si tiene un hash o una matriz que desea serializar, use:
JSON[array_of_values]
O:
JSON[hash_of_values]
Y JSON lo serializará. También puede usar el método to_json
si desea evitar la similitud visual del método []
.
Aquí hay unos ejemplos:
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}]
Si busca en JSON, puede notar que es un subconjunto de YAML y, de hecho, el analizador de YAML es lo que maneja JSON. También puedes hacer esto:
require ''yaml''
YAML.load(string_to_parse)
# => [{"foo"=>1, "bar"=>2}]
Si su aplicación analiza tanto YAML como JSON, puede dejar que YAML maneje ambos tipos de datos serializados.
Esta respuesta es bastante antigua. El pguardiario lo tiene.
Un sitio que hay que revisar es la implementación de JSON para Ruby . Este sitio ofrece una joya que puede instalar para una variante de extensión C mucho más rápida.
Con los puntos de referencia en su página de documentación , afirman que es 21.500 veces más rápido que ActiveSupport::JSON.decode
El código sería el mismo que la respuesta de Milan Novota con esta gema, pero el análisis sería:
parsed_json = JSON(your_json_string)
Estas respuestas son un poco anticuadas. Por eso te doy:
hash = JSON.parse string
Los rieles deben cargar json
módulo json
por usted, por lo que no es necesario agregar require ''json''
.
Esto es lo que yo haría:
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]
Si conoces la URL de origen, entonces puedes usar:
source_url = "http://www.foo.com".to_sym
results.fetch(source_url)[:shortUrl]
=> "http://b.i.t.ly/1a0p8G"
Si no conoce la clave de la URL de origen, puede hacer lo siguiente:
results.fetch(results.keys[0])[:shortUrl]
=> "http://b.i.t.ly/1a0p8G"
Si no desea buscar claves usando símbolos, puede convertir las claves del hash en cadenas:
results = json[:results].stringify_keys
results.fetch(results.keys[0])["shortUrl"]
=> "http://b.i.t.ly/1a0p8G"
Si le preocupa que la estructura JSON pueda cambiar, puede crear un esquema JSON simple y validar el JSON antes de intentar acceder a las claves. Esto proporcionaría un guardia.
NOTA: tuvo que destrozar el bit.ly url debido a las reglas de publicación.
Esto se puede hacer de la siguiente manera, solo necesita usar JSON.parse
, luego puede atravesarlo normalmente con í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"]
La gema Oj ( https://github.com/ohler55/oj ) debería funcionar. Es simple y 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
La gema Oj no funcionará para JRuby. Para JRuby, esta ( https://github.com/ralfstx/minimal-json ) o esta ( https://github.com/clojure/data.json ) pueden ser buenas opciones.
Parsing JSON en Rails es bastante sencillo:
parsed_json = ActiveSupport::JSON.decode(your_json_string)
Supongamos que el objeto con el que desea asociar el shortUrl es un objeto de sitio, que tiene dos atributos: short_url y long_url. Entonces, para obtener el shortUrl y asociarlo con el objeto del sitio apropiado, puede hacer algo como:
parsed_json["results"].each do |longUrl, convertedUrl|
site = Site.find_by_long_url(longUrl)
site.short_url = convertedUrl["shortUrl"]
site.save
end
Puedes probar algo como esto:
def details_to_json
{
:id => self.id,
:credit_period_type => self.credit_period_type,
:credit_payment_period => self.credit_payment_period,
}.to_json
end
RUBY distingue entre mayúsculas y minúsculas.
require ''json'' # json must be lower case
JSON.parse(<json object>)
por ejemplo
JSON.parse(response.body) # JSON must be all upper-case
Ruby tiene un analizador JSON:
require ''json''
require ''json''
hash = JSON.parse string
Trabaja con el hash y haz lo que quieras hacer.
require ''json''
out=JSON.parse(input)
Esto devolverá un hash