Je cherche un moyen simple d'analyser JSON, d'extraire une valeur et de l'écrire dans une base de données dans Rails.
Plus précisément, ce que je recherche, c’est un moyen d’extraire shortUrl
du fichier JSON renvoyé par l’API bit.ly:
{
"errorCode": 0,
"errorMessage": "",
"results":
{
"http://www.foo.com":
{
"hash": "e5TEd",
"shortKeywordUrl": "",
"shortUrl": "http://bit.ly/1a0p8G",
"userHash": "1a0p8G"
}
},
"statusCode": "OK"
}
Et ensuite, prenez ce shortUrl et écrivez-le dans un objet ActiveRecord associé à l'URL longue.
C’est l’une de ces choses auxquelles je peux penser complètement dans le concept et quand je m’assieds pour exécuter, je me rends compte que j’ai beaucoup à apprendre.
Ces réponses sont un peu datées. Donc je te donne:
hash = JSON.parse string
Les rails doivent charger automatiquement le module json
pour vous, de sorte que vous ne soyez pas devez ajouter require 'json'
.
L'analyse de JSON dans Rails est assez simple:
parsed_json = ActiveSupport::JSON.decode(your_json_string)
Supposons que l'objet auquel vous souhaitez associer le shortUrl est un objet Site, qui possède deux attributs: short_url et long_url. Ensuite, pour obtenir le shortUrl et l’associer à l’objet Site approprié, vous pouvez faire quelque chose comme:
parsed_json["results"].each do |longUrl, convertedUrl|
site = Site.find_by_long_url(longUrl)
site.short_url = convertedUrl["shortUrl"]
site.save
end
Cette réponse est assez ancienne. pguardiario l'a eu.
Un site à consulter est implémentation JSON pour Ruby . Ce site offre un bijou que vous pouvez installer pour une variante d’extension C beaucoup plus rapide.
Avec les repères étant donné leur page de documentation ils affirment qu'il est 21.500x plus rapide que ActiveSupport::JSON.decode
Le code serait le même que celui de Milan Novota avec cette gemme, mais l'analyse serait simplement:
parsed_json = JSON(your_json_string)
Voici une mise à jour pour 2013.
Ruby 1.9 a une valeur par défaut gem JSON avec les extensions C. Vous pouvez l'utiliser avec
require 'json'
JSON.parse ''{ "x": "y" }'
# => {"x"=>"y"}
La variante parse!
peut être utilisée pour des sources sûres . Il existe également d'autres joyaux, qui peuvent être plus rapides que l'implémentation par défaut. Veuillez vous référer à multi_json pour la liste.
Les versions modernes de Rails utilisent multi_json , une gemme qui utilise automatiquement la gemme JSON la plus rapide disponible. Ainsi, la méthode recommandée consiste à utiliser
object = ActiveSupport::JSON.decode json_string
Veuillez vous référer à ActiveSupport :: JSON pour plus d'informations. En particulier, la ligne importante dans la source de la méthode est
data = MultiJson.load(json, options)
Ensuite, dans votre Gemfile, incluez les gemmes que vous souhaitez utiliser. Par exemple,
group :production do
gem 'oj'
end
Le paquet de Ruby JSON est capable d’exhiber un peu de magie.
Si vous souhaitez analyser une chaîne contenant des données sérialisées JSON:
_JSON[string_to_parse]
_
JSON examinera le paramètre, verra que c'est une chaîne et essaiera de le décoder.
De même, si vous souhaitez sérialiser un tableau de hachage ou un tableau, utilisez:
_JSON[array_of_values]
_
Ou:
_JSON[hash_of_values]
_
Et JSON le sérialisera. Vous pouvez également utiliser la méthode to_json
si vous souhaitez éviter la similarité visuelle de la méthode []
.
Voici quelques exemples:
_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 vous parcourez JSON, vous remarquerez peut-être qu'il s'agit d'un sous-ensemble de YAML. En réalité, l'analyseur YAML est ce qui gère JSON. Vous pouvez le faire aussi:
_require 'yaml'
YAML.load(string_to_parse)
# => [{"foo"=>1, "bar"=>2}]
_
Si votre application analyse à la fois YAML et JSON, vous pouvez laisser YAML gérer les deux types de données sérialisées.
require 'json'
out=JSON.parse(input)
Cela retournera un hachage
require 'json'
hash = JSON.parse string
travaillez avec le hash et faites ce que vous voulez faire.
Cela peut être fait comme ci-dessous, il suffit d’utiliser JSON.parse
, vous pourrez ensuite le parcourir normalement avec des index.
#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"]
Voici ce que je ferais:
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 vous connaissez l'URL source, vous pouvez utiliser:
source_url = "http://www.foo.com".to_sym
results.fetch(source_url)[:shortUrl]
=> "http://b.i.t.ly/1a0p8G"
Si vous ne connaissez pas la clé de l'URL source, vous pouvez procéder comme suit:
results.fetch(results.keys[0])[:shortUrl]
=> "http://b.i.t.ly/1a0p8G"
Si vous ne souhaitez pas rechercher les clés à l'aide de symboles, vous pouvez convertir les clés du hachage en chaînes:
results = json[:results].stringify_keys
results.fetch(results.keys[0])["shortUrl"]
=> "http://b.i.t.ly/1a0p8G"
Si vous pensez que la structure JSON pourrait changer, vous pouvez créer un schéma JSON simple et valider le JSON avant de tenter d'accéder aux clés. Cela fournirait une garde.
REMARQUE: il a fallu modifier l'URL bit.ly à cause des règles de publication.
Ruby est sensible à la casse.
require 'json' # json must be lower case
JSON.parse(<json object>)
par exemple
JSON.parse(response.body) # JSON must be all upper-case
La gemme Oj ( https://github.com/ohler55/oj ) devrait fonctionner. C'est simple et rapide.
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
Le joyau Oj ne fonctionnera pas pour JRuby. Pour JRuby, ceci ( https://github.com/ralfstx/minimal-json ) ou this ( https://github.com/clojure/data.json ) peut être de bonnes options.