Comment puis-je Parser JSON avec Ruby sur Rails? [dupliquer]

cette question a déjà une réponse ici:

  • l'Analyse d'une chaîne JSON en Ruby 7 réponses

je suis à la recherche d'un moyen simple pour analyser JSON, extraire une valeur et l'écrire dans une base de données dans les Rails.

spécifiquement ce que je cherche, est un moyen de extrait shortUrl du JSON retourné du bit.LY API:

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

et puis prendre ce raccourci et l'écrire dans un objet ActiveRecord associé à la longue URL.

C'est une de ces choses qui, je pense, par entièrement dans le concept et quand je m'assois pour exécuter je me rends compte que j'ai beaucoup à apprendre.

295
demandé sur Arslan Ali 2009-12-01 17:58:01

13 réponses

ces réponses sont un peu désuètes. C'est pourquoi je vous donne:

hash = JSON.parse string

les Rails devraient automatiquement charger le module json pour vous, donc vous ne pas besoin d'ajouter require 'json' .

425
répondu pguardiario 2015-01-08 09:23:19

Parsing JSON dans les Rails est assez simple:

parsed_json = ActiveSupport::JSON.decode(your_json_string)

supposons que l'objet avec lequel vous voulez associer le shortUrl est un objet Site, qui a deux attributs - short_url et long_url. Puis, pour obtenir le shortUrl et l'associer avec l'objet de 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
183
répondu Milan Novota 2009-12-01 16:08:35

cette réponse est assez ancienne. pguardiario s'en occupe.

un site à vérifier est JSON implementation for Ruby . Ce site offre un joyau que vous pouvez installer pour une variante d'extension C beaucoup plus rapide.

avec les repères étant donné leur page de documentation ils prétendent qu'il est 21.500 x plus rapide que ActiveSupport::JSON.decode

le code serait le même que Milan La réponse de Novota avec cette gemme, mais l'analyse serait juste:

parsed_json = JSON(your_json_string)
54
répondu lillq 2012-10-19 07:39:19

Voici une mise à jour pour 2013.

Ruby

Ruby 1.9 a un défaut JSON gem avec des extensions C. Vous pouvez l'utiliser avec

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

la variante parse! peut être utilisée pour les sources sûres . Il y a aussi d'autres gems, qui peuvent être plus rapides que l'implémentation par défaut. Veuillez vous référer à multi_json pour la liste.

Rails

les versions modernes des Rails utilisent multi_json , une gemme qui utilise automatiquement la gemme JSON la plus rapide disponible. Ainsi, la manière recommandée est d'utiliser

object = ActiveSupport::JSON.decode json_string

consultez ActiveSupport::JSON pour plus d'informations. En particulier, la ligne importante dans la source de la méthode est

data = MultiJson.load(json, options)

puis dans votre Gemfile, incluez les gemmes que vous voulez utiliser. Par exemple,

group :production do
  gem 'oj'
end
19
répondu James Lim 2013-08-01 14:48:06

Ruby groupés JSON est capable d'exposer un peu de magie sur son propre.

si vous avez une chaîne contenant des données sérialisées JSON que vous voulez analyser:

JSON[string_to_parse]

JSON va regarder le paramètre, voir que c'est une chaîne et essayer de le décoder.

de même, si vous avez un hachage ou un tableau que vous voulez sérialisé, 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 voulez éviter la similitude 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 root around dans JSON vous pourriez remarquer qu'il s'agit d'un sous-ensemble de YAML, et, en fait, L'analyseur YAML est ce qui manipule 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 saveurs de données sérialisées.

7
répondu the Tin Man 2013-11-06 14:30:39
require 'json'
out=JSON.parse(input)

cela retournera un hachage

5
répondu user2726667 2013-08-28 19:18:09
require 'json'

hash = JSON.parse string

travaillez avec le hash et faites ce que vous voulez.

5
répondu Mohammad Shahadat Hossain 2016-02-27 17:20:39

the Jo gem ( ) 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 Jo gem ne fonctionnera pas pour JRuby. Pour JRuby ceci ( https://github.com/ralfstx/minimal-json ) ou ce ( ) https://github.com/clojure/data.json ) peuvent être de bonnes options.

2
répondu John Moore 2014-05-02 12:22:23

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
2
répondu Steven 2014-10-23 18:35:31

voilà 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 faire ce qui suit:

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

si vous ne voulez pas rechercher des clés en utilisant des symboles, vous pouvez convertir les clés dans le hachage en chaînes:

results = json[:results].stringify_keys

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

si vous craignez que la structure JSON puisse changer, vous pouvez construire un schéma JSON simple et valider le JSON avant d'essayer d'accéder aux clés. Cela permettrait d'avoir une garde.

NOTE: a dû rogner le morceau.ly url à cause des règles de publication.

1
répondu Jurgen 2017-08-27 04:17:23

cela peut être fait comme ci-dessous, juste besoin d'utiliser JSON.parse , alors vous pouvez traverser à travers elle normalement avec des indices.

#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"]
1
répondu Nishant Rawat 2018-02-18 16:42:37

Ruby a un parser JSON:

require 'json'
0
répondu Kiattisak Anoochitarom 2014-10-23 18:35:50

Vous pouvez essayer quelque chose comme ceci:

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

 }.to_json
end
-2
répondu John Moore 2013-08-14 08:44:24