Get a particular key value from json in ruby - ruby-on-rails

[
"KEY1":{"SUB_KEY1" : "VALUE1","SUB_KEY2" : "VALUE2"},
"KEY2":{"SUB_KEY1" : "VALUE1","SUB_KEY2" : "VALUE2"}
]
The above is my json object which is coming as a response.
How do I get SUB_KEY1 of KEY1 and SUB_KEY1 of KEY2 in Ruby on Rails?
Thank you.

You need to parse the JSON object into a ruby hash. Assuming your JSON response is called res:
require 'json'
obj = JSON.parse(res)
sv1 = obj['KEY1']['SUB_KEY1']
etc.

parsed_json = ActiveSupport::JSON.decode(your_json_string)
will parse your string as
[{"KEY1"=>{"SUB_KEY1"=>"VALUE1", "SUB_KEY2"=>"VALUE2"}}, {"KEY2"=>{"SUB_KEY1"=>"VALUE1", "SUB_KEY2"=>"VALUE2"}}]
You should be able to access it using something like parsed_json[1]["KEY2"]["SUB_KEY1"]

You need to parse JSON data first. Then loop over the JSON object to access the key as follow:
#response = JSON.parse(HTTParty.get(your_url).body)
#response["data"].each do |key|
puts data[0][key]
puts data[0][key2]
end

Related

how to convert the given string to array in rails

I have the following Strings. I want them to convert into Arrays like below in rails
"[\"Winter\", \"Summer\", \"Spring\"]" to ["Winter", "Summer", "Spring"]
"[\"IELTS\", \"GRE\", \"PTE\", \"SAT\"]" to ["IELTS", "GRE", "PTE", "SAT"]
How can i convert these
You can do it with JSON.
require 'json'
string = "[\"Winter\", \"Summer\", \"Spring\"]"
JSON.parse(string)
=> ["Winter", "Summer", "Spring"]
just alternate solution (not safe) :
> string = "[\"Winter\", \"Summer\", \"Spring\"]"
> eval(string)
#=> ["Winter", "Summer", "Spring"]
Note: better option to parse with JSON

Generate a Key, Value JSON object from a Ruby Object Array

I have a Ruby array of students. Student class has attributes id, name and age.
students = [
{id:"id1",name:"name1",age:"age1"},
{id:"id2",name:"name2",age:"age2"},
{id:"id3",name:"name3",age:"age3"}
]
I want to create a JSON key value object from this array as follows.
json_object = {id1:name1, id2:name2, id3:name3}
input = [ {id:"id1",name:"name1",age:"age1"},
{id:"id2",name:"name2",age:"age2"},
{id:"id3",name:"name3",age:"age3"}]
require 'json'
JSON.dump(input.map { |hash| [hash[:id], hash[:name]] }.to_h)
#⇒ '{"id1":"name1","id2":"name2","id3":"name3"}'
Give this a go:
students = [
{id:"id1",name:"name1",age:"age1"},
{id:"id2",name:"name2",age:"age2"},
{id:"id3",name:"name3",age:"age3"}
]
json_object = students.each_with_object({}) do |hsh, returning|
returning[hsh[:id]] = hsh[:name]
end.to_json
In console:
puts json_object
=> {"id1":"name1","id2":"name2","id3":"name3"}
Your data is all identical, but if you wanted to generate a hash that took the value of students[n][:id] as keys and students[n][:name] as values you could do this:
student_ids_to_names = students.each_with_object({}) do |student, memo|
memo[student[:id]] = student[:name]
end
For your data, you'd end up with only one entry as the students are identical: { "id1" => "name1" }. If the data were different each key would be unique on :id.
Once you have a hash, you can call json_object = students_ids_to_names.to_json to get a JSON string.

Splitting response of Savon

Somehow, the webservice I am using savon to deal with returns this response
{:do_deal_response=>{:do_deal_result=>"Code=000&CardNumber=0000&CardDate=12/18&PayDate=02/01/2017&BusinessName=בדיקות&Terminal=0962317010&ActionMethod=עסקה טלפונית&DealID=5349614&DealType=אשראי רגיל&DealTypeOut=עסקת חובה רגילה 0000000&OkNumber=0000000&DealDate=06/12/2016 11:00:14&PayNumber=&TotalSum=111&FirstPay=&CardName=ויזה כ.א.ל&CardNameID=2&AuthNum=0000000&DealNumber=06370507&ParamJ=J4&ErrorDesc=עסקה תקינה.&Currency=שקלים&CurrencyID=1&Manpik=ויזה כ.א.ל&ManpikID=2&Mutag=ויזה כ.א.ל&MutagID=2", :#xmlns=>"http://tempuri.org/"}}
accessing #response[:do_deal_response][:do_deal_result] obviously returns the string
"Code=000&CardNumber=0000&CardDate=12/18&PayDate=02/01/2017&BusinessName=בדיקות&Terminal=0962317010&ActionMethod=עסקה טלפונית&DealID=5349614&DealType=אשראי רגיל&DealTypeOut=עסקת חובה רגילה 0000000&OkNumber=0000000&DealDate=06/12/2016 11:00:14&PayNumber=&TotalSum=111&FirstPay=&CardName=ויזה כ.א.ל&CardNameID=2&AuthNum=0000000&DealNumber=06370507&ParamJ=J4&ErrorDesc=עסקה תקינה.&Currency=שקלים&CurrencyID=1&Manpik=ויזה כ.א.ל&ManpikID=2&Mutag=ויזה כ.א.ל&MutagID=2"
I want to be able to access this string as a hash with with symbols
like:
results[:code] = "000"
Instead of manually parsing, you can use the following:
require 'cgi'
parsed = CGI.parse(#response[:do_deal_response][:do_deal_result])
parsed['Code']
#=> ["000"]
Since this accepts multiple values for each key values are always wrapped in an array. If that bothers you, you can do one more transformation step with map (or map_values if you use Rails):
parsed.map { |k, v| [k.underscore.symbolize, v.size == 1 ? v.first : v] }.to_h
#=> => {:code=>"000", :card_number=>"0000", :ard_date=>"12/18", :pay_date=>"02/01/2017",...
This will only unwrap arrays with one element, everything else will stay in an array.
Stand-alone solution
This code could help you. It just splits the string around &, split every part around = and saves them as key and value in a Hash :
response = {:do_deal_response=>{:do_deal_result=>"Code=000&CardNumber=0000&CardDate=12/18&PayDate=02/01/2017&BusinessName=בדיקות&Terminal=0962317010&ActionMethod=עסקה טלפונית&DealID=5349614&DealType=אשראי רגיל&DealTypeOut=עסקת חובה רגילה 0000000&OkNumber=0000000&DealDate=06/12/2016 11:00:14&PayNumber=&TotalSum=111&FirstPay=&CardName=ויזה כ.א.ל&CardNameID=2&AuthNum=0000000&DealNumber=06370507&ParamJ=J4&ErrorDesc=עסקה תקינה.&Currency=שקלים&CurrencyID=1&Manpik=ויזה כ.א.ל&ManpikID=2&Mutag=ויזה כ.א.ל&MutagID=2", :#xmlns=>"http://tempuri.org/"}}
deal_result = response[:do_deal_response][:do_deal_result]
class String
def underscore
self.gsub(/::/, '/').
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
gsub(/([a-z\d])([A-Z])/,'\1_\2').
tr("-", "_").
downcase
end
end
results = deal_result.split('&').each_with_object({}) do |string, h|
key, value = string.split('=')
h[key.underscore.to_sym] = value
end
puts results
#=> {:code=>"000", :card_number=>"0000", :card_date=>"12/18", :pay_date=>"02/01/2017", :business_name=>"בדיקות", :terminal=>"0962317010", :action_method=>"עסקה טלפונית", :deal_id=>"5349614", :deal_type=>"אשראי רגיל", :deal_type_out=>"עסקת חובה רגילה 0000000", :ok_number=>"0000000", :deal_date=>"06/12/2016 11:00:14", :pay_number=>nil, :total_sum=>"111", :first_pay=>nil, :card_name=>"ויזה כ.א.ל", :card_name_id=>"2", :auth_num=>"0000000", :deal_number=>"06370507", :param_j=>"J4", :error_desc=>"עסקה תקינה.", :currency=>"שקלים", :currency_id=>"1", :manpik=>"ויזה כ.א.ל", :manpik_id=>"2", :mutag=>"ויזה כ.א.ל", :mutag_id=>"2"}
With Rack
If you have Rack installed :
require 'rack'
puts Rack::Utils.parse_nested_query(deal_result).map { |k, v| [k.underscore.to_sym, v] }.to_h
Both answers match exactly the structure you were looking for : snakecase symbol for key and non Array values.

passing array through Net::HTTP

I'm trying to pass an array through Net::HTTP to a ruby
def send_p
x = Net::HTTP.post_form(URI.parse('http://example_domain/example'), to_send)
render text: x
end
def to_send
{
param_a: "foo",
param_b: [1,2,3]
}
end
but when check the params in http://example_domain/example is getting me
{
"param_a"=>"foo",
"param_b"=>"3",
"action"=>"my_method",
"controller"=>"my_controller"
}
what can I do to receive the array in the proper way: [1,2,3]
Try using HTTParty:
x = HTTParty.post(URI.parse('http://example_domain/example'), to_send)
You can convert the array to string and then do the inverse when getting the params from the response.
Convert to String before to send it
param_b: [1,2,3].to_s
You will receive exactly as you sent it
"param_b"=>"[1,2,3]"
Convert it back to Array
eval(params[:param_b])
# => [1, 2, 3]

Array values to keys?

I am parsing some XML to JSON and then serving this on http://floating-gorge-9520.herokuapp.com/currencies.
I want to display the data so the values for currency are the keys and the values for rate then become the values for the new currency data.
For example:
USD: 1
GBP: 0.5
What is the best way of doing this?
Using two currencies for simplicity:
require 'json'
a = [{"currency"=>"USD", "rate"=>"1.3707"},
{"currency"=>"JPY", "rate"=>"140.50"}]
Hash[a.map { |h| [h['currency'],h['rate'].to_f] }]
# => {"USD"=>1.3707, "JPY"=>140.5}
Just append a .to_json on the last statement to get the JSON string.
Check this out
require 'json'
a = {}
json = '[{"currency":"USD","rate":"1.3707"},{"currency":"JPY","rate":"140.50"},{"currency":"BGN","rate":"1.9558"},{"currency":"CZK","rate":"27.368"},{"currency":"DKK","rate":"7.4625"},{"currency":"GBP","rate":"0.82183"},{"currency":"HUF","rate":"311.89"},{"currency":"LTL","rate":"3.4528"},{"currency":"PLN","rate":"4.1661"},{"currency":"RON","rate":"4.5222"},{"currency":"SEK","rate":"8.9953"},{"currency":"CHF","rate":"1.2195"},{"currency":"NOK","rate":"8.3670"},{"currency":"HRK","rate":"7.6685"},{"currency":"RUB","rate":"49.0415"},{"currency":"TRY","rate":"3.0097"},{"currency":"AUD","rate":"1.5283"},{"currency":"BRL","rate":"3.2577"},{"currency":"CAD","rate":"1.5304"},{"currency":"CNY","rate":"8.3495"},{"currency":"HKD","rate":"10.6313"},{"currency":"IDR","rate":"16097.50"},{"currency":"ILS","rate":"4.8062"},{"currency":"INR","rate":"85.1580"},{"currency":"KRW","rate":"1469.53"},{"currency":"MXN","rate":"18.2348"},{"currency":"MYR","rate":"4.5158"},{"currency":"NZD","rate":"1.6558"},{"currency":"PHP","rate":"61.092"},{"currency":"SGD","rate":"1.7376"},{"currency":"THB","rate":"44.603"},{"currency":"ZAR","rate":"15.1355"}]';
JSON.parse(json).each { |x| a[x['currency']] = x['rate'] }
print a

Resources