How do I parse JSON with Ruby on Rails? [duplicate

2019-01-01 10:25发布

问题:

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