Ich suche nach einer einfachen Möglichkeit, JSON zu analysieren, einen Wert zu extrahieren und in Rails in eine Datenbank zu schreiben.
Insbesondere suche ich nach einer Möglichkeit, shortUrl
aus dem von der bit.ly-API zurückgegebenen JSON zu extrahieren:
{
"errorCode": 0,
"errorMessage": "",
"results":
{
"http://www.foo.com":
{
"hash": "e5TEd",
"shortKeywordUrl": "",
"shortUrl": "http://bit.ly/1a0p8G",
"userHash": "1a0p8G"
}
},
"statusCode": "OK"
}
Nehmen Sie dann diese shortUrl und schreiben Sie sie in ein ActiveRecord-Objekt, das der langen URL zugeordnet ist.
Dies ist eines der Dinge, die ich ganz im Konzept durchdenken kann, und wenn ich mich hinsetze, um sie auszuführen, stelle ich fest, dass ich viel lernen muss.
Diese Antworten sind etwas veraltet. Deshalb gebe ich dir:
hash = JSON.parse string
Rails sollte das json
-Modul automatisch für Sie laden, sodass Sie nichtrequire 'json'
Hinzufügen müssen.
Das Parsen von JSON in Rails ist ganz einfach:
parsed_json = ActiveSupport::JSON.decode(your_json_string)
Angenommen, das Objekt, dem Sie die shortUrl zuordnen möchten, ist ein Site-Objekt mit zwei Attributen - short_url und long_url. Um die shortUrl abzurufen und mit dem entsprechenden Site-Objekt zu verknüpfen, können Sie Folgendes tun:
parsed_json["results"].each do |longUrl, convertedUrl|
site = Site.find_by_long_url(longUrl)
site.short_url = convertedUrl["shortUrl"]
site.save
end
Diese Antwort ist ziemlich alt. pguardiario hat es verstanden.
Eine Seite, die Sie auschecken sollten, ist JSON-Implementierung für Ruby . Diese Seite bietet ein Juwel, das Sie für eine viel schnellere C-Erweiterungsvariante installieren können.
Mit den Benchmarks als Dokumentationsseite behaupten sie, dass es 21.500x schneller ist als ActiveSupport::JSON.decode
Der Code wäre derselbe wie die Antwort von Milan Novota mit diesem Juwel, aber das Parsen wäre einfach:
parsed_json = JSON(your_json_string)
Hier ist ein Update für 2013.
Ruby 1.9 hat eine Standardeinstellung JSON-Gem mit C-Erweiterungen. Sie können es mit verwenden
require 'json'
JSON.parse ''{ "x": "y" }'
# => {"x"=>"y"}
Das parse!
variant kann für sichere Quellen verwendet werden. Es gibt auch andere Juwelen, die möglicherweise schneller als die Standardimplementierung sind. Die Liste finden Sie unter multi_json .
Moderne Versionen von Rails use multi_json , einem Juwel, das automatisch das schnellste verfügbare JSON-Juwel verwendet. Daher wird die Verwendung empfohlen
object = ActiveSupport::JSON.decode json_string
Weitere Informationen finden Sie unter ActiveSupport :: JSON . Insbesondere ist die wichtige Zeile in der Methodenquelle
data = MultiJson.load(json, options)
Fügen Sie dann in Ihre Gemdatei die Edelsteine ein, die Sie verwenden möchten. Zum Beispiel,
group :production do
gem 'oj'
end
Rubys gebündeltes JSON ist in der Lage, selbst ein bisschen Magie zu entfalten.
Wenn Sie eine Zeichenfolge mit JSON-serialisierten Daten haben, die Sie analysieren möchten:
JSON[string_to_parse]
JSON überprüft den Parameter, ob es sich um einen String handelt, und versucht, ihn zu dekodieren.
Wenn Sie über einen Hash oder ein Array verfügen, das serialisiert werden soll, verwenden Sie Folgendes:
JSON[array_of_values]
Oder:
JSON[hash_of_values]
Und JSON wird es serialisieren. Sie können auch die to_json
Methode, wenn Sie die visuelle Ähnlichkeit der []
Methode .
Hier sind einige Beispiele:
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}]
Wenn Sie in JSON herumwühlen, stellen Sie möglicherweise fest, dass es sich um eine Teilmenge von YAML handelt, und tatsächlich ist der YAML-Parser das, was JSON behandelt. Sie können dies auch tun:
require 'yaml'
YAML.load(string_to_parse)
# => [{"foo"=>1, "bar"=>2}]
Wenn Ihre App sowohl YAML als auch JSON analysiert, können Sie YAML beide Arten von serialisierten Daten verarbeiten lassen.
require 'json'
out=JSON.parse(input)
Dies gibt einen Hash zurück
require 'json'
hash = JSON.parse string
arbeite mit dem Hash und mach was du willst.
Dies kann wie folgt durchgeführt werden, muss nur JSON.parse
, dann können Sie es normal mit Indizes durchlaufen.
#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"]
Folgendes würde ich tun:
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]
Wenn Sie die Quell-URL kennen, können Sie Folgendes verwenden:
source_url = "http://www.foo.com".to_sym
results.fetch(source_url)[:shortUrl]
=> "http://b.i.t.ly/1a0p8G"
Wenn Sie den Schlüssel für die Quell-URL nicht kennen, können Sie Folgendes tun:
results.fetch(results.keys[0])[:shortUrl]
=> "http://b.i.t.ly/1a0p8G"
Wenn Sie Schlüssel nicht mit Symbolen suchen möchten, können Sie die Schlüssel im Hash in Zeichenfolgen konvertieren:
results = json[:results].stringify_keys
results.fetch(results.keys[0])["shortUrl"]
=> "http://b.i.t.ly/1a0p8G"
Wenn Sie befürchten, dass sich die JSON-Struktur ändert, können Sie ein einfaches JSON-Schema erstellen und das JSON validieren, bevor Sie versuchen, auf Schlüssel zuzugreifen. Dies würde eine Wache bieten.
HINWEIS: Die bit.ly-URL musste aufgrund von Veröffentlichungsregeln entstellt werden.
Ruby unterscheidet zwischen Groß- und Kleinschreibung.
require 'json' # json must be lower case
JSON.parse(<json object>)
zum Beispiel
JSON.parse(response.body) # JSON must be all upper-case
Das Oj-Juwel ( https://github.com/ohler55/oj ) sollte funktionieren. Es ist einfach und schnell.
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
Der Oj-Edelstein wird für JRuby nicht funktionieren. Für JRuby kann dies ( https://github.com/ralfstx/minimal-json ) oder dies ( https://github.com/clojure/data.json ) sein Gute Möglichkeiten.