可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
This question already has an answer here:
-
Parsing a JSON string in Ruby
7 answers
I\'m looking for a simple way to parse JSON, extract a value and write it into a database in Rails.
Specifically what I\'m looking for, is a way to extract shortUrl
from the JSON returned from the bit.ly API:
{
\"errorCode\": 0,
\"errorMessage\": \"\",
\"results\":
{
\"http://www.foo.com\":
{
\"hash\": \"e5TEd\",
\"shortKeywordUrl\": \"\",
\"shortUrl\": \"http://bit.ly/1a0p8G\",
\"userHash\": \"1a0p8G\"
}
},
\"statusCode\": \"OK\"
}
And then take that shortUrl and write it into an ActiveRecord object associated with the long URL.
This is one of those things that I can think through entirely in concept and when I sit down to execute I realize I\'ve got a lot to learn.
回答1:
These answers are a bit dated. Therefore I give you:
hash = JSON.parse string
Rails should automagically load the json
module for you, so you don\'t need to add require \'json\'
.
回答2:
Parsing JSON in Rails is quite straightforward:
parsed_json = ActiveSupport::JSON.decode(your_json_string)
Let\'s suppose, the object you want to associate the shortUrl with is a Site object, which has two attributes - short_url and long_url. Than, to get the shortUrl and associate it with the appropriate Site object, you can do something like:
parsed_json[\"results\"].each do |longUrl, convertedUrl|
site = Site.find_by_long_url(longUrl)
site.short_url = convertedUrl[\"shortUrl\"]
site.save
end
回答3:
This answer is quite old. pguardiario\'s got it.
One site to check out is JSON implementation for Ruby. This site offers a gem you can install for a much faster C extension variant.
With the benchmarks given their documentation page they claim that it is 21.500x faster than ActiveSupport::JSON.decode
The code would be the same as Milan Novota\'s answer with this gem, but the parsing would just be:
parsed_json = JSON(your_json_string)
回答4:
Here is an update for 2013.
Ruby
Ruby 1.9 has a default JSON gem with C extensions. You can use it with
require \'json\'
JSON.parse \'\'{ \"x\": \"y\" }\'
# => {\"x\"=>\"y\"}
The parse!
variant can be used for safe sources. There are also other gems, which may be faster than the default implementation. Please refer to multi_json for the list.
Rails
Modern versions of Rails use multi_json, a gem that automatically uses the fastest JSON gem available. Thus, the recommended way is to use
object = ActiveSupport::JSON.decode json_string
Please refer to ActiveSupport::JSON for more information. In particular, the important line in the method source is
data = MultiJson.load(json, options)
Then in your Gemfile, include the gems you want to use. For example,
group :production do
gem \'oj\'
end
回答5:
Ruby\'s bundled JSON is capable of exhibiting a bit of magic on its own.
If you have a string containing JSON serialized data that you want to parse:
JSON[string_to_parse]
JSON will look at the parameter, see it\'s a String and try decoding it.
Similarly, if you have a hash or array you want serialized, use:
JSON[array_of_values]
Or:
JSON[hash_of_values]
And JSON will serialize it. You can also use the to_json
method if you want to avoid the visual similarity of the []
method.
Here are some examples:
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}]
If you root around in JSON you might notice it\'s a subset of YAML, and, actually the YAML parser is what\'s handling JSON. You can do this too:
require \'yaml\'
YAML.load(string_to_parse)
# => [{\"foo\"=>1, \"bar\"=>2}]
If your app is parsing both YAML and JSON, you can let YAML handle both flavors of serialized data.
回答6:
require \'json\'
out=JSON.parse(input)
This will return a Hash
回答7:
require \'json\'
hash = JSON.parse string
work with the hash and do what you want to do.
回答8:
The Oj gem (https://github.com/ohler55/oj) should work. It\'s simple and fast.
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
The Oj gem won\'t work for JRuby. For JRuby this (https://github.com/ralfstx/minimal-json) or this (https://github.com/clojure/data.json) may be good options.
回答9:
RUBY is case sensitive.
require \'json\' # json must be lower case
JSON.parse(<json object>)
for example
JSON.parse(response.body) # JSON must be all upper-case
回答10:
Here\'s what I would do:
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]
If you know the source url then you can use:
source_url = \"http://www.foo.com\".to_sym
results.fetch(source_url)[:shortUrl]
=> \"http://b.i.t.ly/1a0p8G\"
If you don\'t know the key for the source url you can do the following:
results.fetch(results.keys[0])[:shortUrl]
=> \"http://b.i.t.ly/1a0p8G\"
If you\'re not wanting to lookup keys using symbols, you can convert the keys in the hash to strings:
results = json[:results].stringify_keys
results.fetch(results.keys[0])[\"shortUrl\"]
=> \"http://b.i.t.ly/1a0p8G\"
If you\'re concerned the JSON structure might change you could build a simple JSON Schema and validate the JSON before attempting to access keys. This would provide a guard.
NOTE: Had to mangle the bit.ly url because of posting rules.
回答11:
This can be done as below, just need to use JSON.parse
, then you can traverse through it normally with 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\"]
回答12:
Ruby has a JSON parser:
require \'json\'
回答13:
You can try something like this:
def details_to_json
{
:id => self.id,
:credit_period_type => self.credit_period_type,
:credit_payment_period => self.credit_payment_period,
}.to_json
end