Extracting a url comprised of a hash in ruby - ruby

I have a query string that looks as follows:
http://localhost:3000/events?appointment_practices%5B10%5D=Injury&appointment_practices%5B18%5D=Immigration&appointment_practices%5B8%5D=Bankruptcy
appointment_practices is actually a hash I inserted into the query string during a redirect:
appointment_practices = practices.reduce({}) do |acc, practice|
acc[practice.id] = practice.class.name
acc
end
redirect_to events_path(appointment_practices: appointment_practices)
Now I want to parse that query string. When I tried to parse it with decode_www_form, it returns an array with a nil element:
[nil]
This is the code that is giving me the nil element:
#http_refer = #_env['HTTP_REFERER']
begin
uri = URI.parse #http_refer
practices = Hash[URI::decode_www_form(uri.query)].values_at('appointment_practices')
puts "practices: #{practices}"
rescue StandardError
end
I am trying to extract the hash. For example, in appointment_practices%5B10%5D=Injury, the id is 10 and the practice is Injury.
What other options do I have besides regex?

You can use Rack::Utils.parse_nested_query:
require 'uri'
require 'rack'
uri = URI.parse('http://localhost:3000/events?appointment_practices%5B10%5D=Injury&appointment_practices%5B18%5D=Immigration&appointment_practices%5B8%5D=Bankruptcy')
Rack::Utils.parse_nested_query(uri.query)
#=> {"appointment_practices"=>{"10"=>"Injury", "18"=>"Immigration", "8"=>"Bankruptcy"}}

Related

How to get API and manipulate it

With Ruby, no Rails, how can I call an API such as http://api.anapi.com/, and later get a value and check if it is greater than 5?
If it contains an array called "anarray" which contains hashes, in one of those hashes I want to get to the value of the key "key".
Right now I use:
require "net/https"
require "uri"
uri = URI.parse("http://api.cryptocoincharts.info/tradingPair/eth_btc")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
puts response.body
And I get: #<StringIO:0x2cadb90>
Figured it out:
# http://ruby-doc.org/stdlib-2.0.0/libdoc/open-uri/rdoc/OpenURI.html
require 'open-uri'
# https://github.com/flori/json
require 'json'
# http://stackoverflow.com/questions/9008847/what-is-difference-between-p-and-pp
require 'pp'
buffer = open('http://api.cryptocoincharts.info/tradingPair/eth_btc').read
# api_key = "FtHwuH8w1RDjQpOr0y0gF3AWm8sRsRzncK3hHh9"
result = JSON.parse(buffer)
puts result["markets"]
# result.each do |user|
# puts "#{user['id']}\t#{user['name']}\t#{user['email']}"
# puts "Registered: #{user['created_at']}\n\n"
# end
# my_hash = JSON.parse('{"hello": "goodbye"}')
# puts my_hash["hello"] => "goodbye"
With Net::HTTP:
require 'net/http'
uri = URI('http://example.com/index.html?count=10')
Net::HTTP.get(uri) # => String
Then you can do whatever you want with the data. If for example the API returns JSON, you can parse the String with Ruby's JSON module.

Dynamically check if a field in JSON is nil without using eval

Here's an extract of the code that I am using:
def retrieve(user_token, quote_id, check="quotes")
end_time = Time.now + 15
match = false
until Time.now > end_time || match
#response = http_request.get(quote_get_url(quote_id, user_token))
eval("match = !JSON.parse(#response.body)#{field(check)}.nil?")
end
match.eql?(false) ? nil : #response
end
private
def field (check)
hash = {"quotes" => '["quotes"][0]',
"transaction-items" => '["quotes"][0]["links"]["transactionItems"]'
}
hash[check]
end
I was informed that using eval in this manner is not good practice. Could anyone suggest a better way of dynamically checking the existence of a JSON node (field?). I want this to do:
psudo: match = !JSON.parse(#response.body) + dynamic-path + .nil?
Store paths as arrays of path elements (['quotes', 0]). With a little helper function you'll be able to avoid eval. It is, indeed, completely inappropriate here.
Something along these lines:
class Hash
def deep_get(path)
path.reduce(self) do |memo, path_element|
return unless memo
memo[path_element]
end
end
end
path = ['quotes', 0]
hash = JSON.parse(response.body)
match = !hash.deep_get(path).nil?

Obtain BigQuery table list in Ruby

I would like to use the Google bigquery gem (https://rubygems.org/gems/bigquery) to create an Array of table names. So far, this is what I have written:
require 'json'
bqRepsonse = bq.tables('myDataSet')
bqRepsonseCleaned = bqRepsonse.to_s.gsub("=>", ":")
data = JSON.parse(bqRepsonseCleaned)
tableListing = []
data["tableID"]["type"].each do |item|
case item["type"]
when 'TABLE'
bqTableList << item["tableId"]
else
end
end
If I print bqResponse, I get this result:
[{"kind"=>"bigquery#table",
"id"=>"curious-idea-532:dataset_test_4.TableA",
"tableReference"=>{"projectId"=>"curious-idea-532",
"datasetId"=>"dataset_test_4", "tableId"=>"TableA"}, "type"=>"TABLE"},
{"kind"=>"bigquery#table",
"id"=>"curious-idea-532:dataset_test_4.TableB",
"tableReference"=>{"projectId"=>"curious-idea-532",
"datasetId"=>"dataset_test_4", "tableId"=>"TableB"}, "type"=>"TABLE"},
{"kind"=>"bigquery#table",
"id"=>"curious-idea-532:dataset_test_4.TableC",
"tableReference"=>{"projectId"=>"curious-idea-532",
"datasetId"=>"dataset_test_4", "tableId"=>"TableC"}, "type"=>"TABLE"},
{"kind"=>"bigquery#table",
"id"=>"curious-idea-532:dataset_test_4.TableD",
"tableReference"=>{"projectId"=>"curious-idea-532",
"datasetId"=>"dataset_test_4", "tableId"=>"TableD"}, "type"=>"TABLE"}]
And running the code throws and error
`[]': no implicit conversion of String into Integer (TypeError)
Not sure where to correct this. My desired outcome is:
tableListing = ["TableA","TableB","TableC","TableD"]
Thanks in advance for your advice.
Try this:
require 'json'
string = '[{"kind": "bigquery#table", "id": "curious-idea-532:dataset_test_4.TableA", "tableReference" : {"projectId":"curious-idea-532", "datasetId":"dataset_test_4", "tableId":"TableA"}, "type":"TABLE"}, {"kind":"bigquery#table", "id":"curious-idea-532:dataset_test_4.TableB", "tableReference":{"projectId":"curious-idea-532", "datasetId":"dataset_test_4", "tableId":"TableB"}, "type":"TABLE"}, {"kind":"bigquery#table", "id":"curious-idea-532:dataset_test_4.TableC", "tableReference":{"projectId":"curious-idea-532", "datasetId":"dataset_test_4", "tableId":"TableC"}, "type":"TABLE"}, {"kind":"bigquery#table", "id":"curious-idea-532:dataset_test_4.TableD", "tableReference":{"projectId":"curious-idea-532", "datasetId":"dataset_test_4", "tableId":"TableD"}, "type":"TABLE"}]'
data = JSON.parse(string)
tableListing = []
# Here we are iterating over the data instead of its child element
data.each do |item|
case item["type"]
when 'TABLE'
tableListing << item["tableReference"]["tableId"]
else
end
end
puts tableListing

Convert JSON to string or hash in ruby

I have tried:
require 'net/http'
require 'json'
require 'pp'
require 'uri'
url = "http://xyz.com"
resp = Net::HTTP.get_response(URI.parse(url))
buffer = resp.body
result = JSON.parse(buffer)
#result.to_hash
#pp result
puts result
And got the output as:
{"id"=>"ABC", "account_id"=>"123", "first_name"=> "PEUS" }
in JSON format but I only need the value of id to be printed as ABC.
Your incoming string in JSON would look like:
{"id":"ABC","account_id":"123","first_name":"PEUS"}
After parsing with JSON it's the hash:
{"id"=>"ABC", "account_id"=>"123", "first_name"=> "PEUS" }
So, I'd use:
hash = {"id"=>"ABC", "account_id"=>"123", "first_name"=> "PEUS" }
hash['id'] # => "ABC"
Here's a more compact version:
require 'json'
json = '{"id":"ABC","account_id":"123","first_name":"PEUS"}'
hash = JSON[json]
hash['id'] # => "ABC"
Note I'm using JSON[json]. The JSON [] class method is smart enough to sense what the parameter being passed in is. If it's a string it'll parse the string. If it's an Array or Hash it'll serialize it. I find that handy because it allows me to write JSON[...] instead of having to remember whether I'm parsing or using to_json or something. Using it is an example of the first virtue of programmers.

Automatically Map JSON Objects into Instance Variables in Ruby

I would like to be able to automatically parse JSON objects into instance variables. For example, with this JSON.
require 'httparty'
json = HTTParty.get('http://api.dribbble.com/players/simplebits') #=> {"shots_count":150,"twitter_screen_name":"simplebits","avatar_url":"http://dribbble.com/system/users/1/avatars/thumb/dancederholm-peek.jpg?1261060245","name":"Dan Cederholm","created_at":"2009/07/07 21:51:22 -0400","location":"Salem, MA","following_count":391,"url":"http://dribbble.com/players/simplebits","draftees_count":104,"id":1,"drafted_by_player_id":null,"followers_count":2214}
I'd like to be able to do this:
json.shots_count
And have it output:
150
How could I possibly do this?
You should definitely use something like json["shots_counts"], but if you really need objectified hash, you could create a new class for this:
class ObjectifiedHash
def initialize hash
#data = hash.inject({}) do |data, (key,value)|
value = ObjectifiedHash.new value if value.kind_of? Hash
data[key.to_s] = value
data
end
end
def method_missing key
if #data.key? key.to_s
#data[key.to_s]
else
nil
end
end
end
After that, use it:
ojson = ObjectifiedHash.new(HTTParty.get('http://api.dribbble.com/players/simplebits'))
ojson.shots_counts # => 150
Well, getting what you want is hard, but getting close is easy:
require 'json'
json = JSON.parse(your_http_body)
puts json['shots_count']
Not exactly what you are looking for, but this will get you closer:
ruby-1.9.2-head > require 'rubygems'
=> false
ruby-1.9.2-head > require 'httparty'
=> true
ruby-1.9.2-head > json = HTTParty.get('http://api.dribbble.com/players/simplebits').parsed_response
=> {"shots_count"=>150, "twitter_screen_name"=>"simplebits", "avatar_url"=>"http://dribbble.com/system/users/1/avatars/thumb/dancederholm-peek.jpg?1261060245", "name"=>"Dan Cederholm", "created_at"=>"2009/07/07 21:51:22 -0400", "location"=>"Salem, MA", "following_count"=>391, "url"=>"http://dribbble.com/players/simplebits", "draftees_count"=>104, "id"=>1, "drafted_by_player_id"=>nil, "followers_count"=>2214}
ruby-1.9.2-head > puts json["shots_count"]
150
=> nil
Hope this helps!

Resources