Data from a JSON API combined with local database in Rails - ruby-on-rails

I would like to combine data retrieved from an API with local database data in a new JSON. But I think I'm doing this wrong. Here is my code :
#data = ActiveSupport::JSON.decode(#api_data)
#data.each do |key|
if key['state'] == "active"
user_id = key['id']
user_database = User.where(:user_id => user_id).take
#userlist = []
unless user_database.blank?
user_data = {
:user_id => key['id'],
:enrolement_start_date => key['start_at'],
:enrolement_end_date => key['end_at'],
:user_interest => user_database.interests,
:user_discipline_id => user_database.discipline_id,
}
#userlist.push(user_data)
end
end
end
#userlist = #userlist.to_json
Actually, it's working but I only receive the last user as result. I don't figure how to make it works :-/ Many thanks in advance !

#userlist = []
that line, each time through the loop
#data.each do |key|
is clearing out the previous data by re-initializing #userlist. Then you're returning the user you added last, since all the others were thrown away the last time you assigned an empty array to #userlist.
Just move
#userlist = []
above
#data.each do |key|
and you should be good.

Related

Assigning a ruby hash by map do where values don't consistantly exist

I have an map that I have to assemble before using...
mailList = Customers.map do |customer|
{
:username => customer.name,
:email => customer.email,
:last_ip_v4 => customer.ipv4,
:last_ip_v6 => customer.ipv6
}
end
This works for a number of test users, but not all users have a last ipv4 AND a last ipv6. When they don't, ruby errors out, but I'd rather it just assign a nil. How do I do that?
If you are sure that this line,
mailList = Customers.map do |customer|
will work fine (may be incase of using a wrong convention), then try to check the nil cases for ipv4 and ipv6 and construct the list as,
mailList = construct_list Customers
def construct_list data
list = []
hash ={}
data.map do |customer|
hash[:username] = customer.name
hash[:email] = customer.email
customer.ipv4.nil? ? hash[:last_ip_v4] = nil : hash[:last_ip_v4] = customer.ipv4
customer.ipv6.nil? ? hash[:last_ip_v6] = nil : hash[:last_ip_v6] = customer.ipv6
list << hash
end
list
end
Though it may not be optimal, it will help you for a while.
Even if ipv4 and ipv6 are nil, it should not throw error. I think the syntax here is incorrect or Customers is nil. Try this way:
mailList = Customer.all.map do |customer|
{
username: customer.name,
email: customer.email,
last_ip_v4: customer.ipv4,
last_ip_v6: customer.ipv6
}
end

How to format data Rails

I need to retrieve data from database column and put them to
[{1442507641,1},{1442507642,2},{1442507643,3},{1442507644,4}...]
format as the plot format requires.
I'm trying to do this by :
#data = TableName.where(:id => requiredid)
.map {|r| { r.received_date.to_i => r.value } }
but this returns format
data=[{1442507641=>6}, {1442507641=>7}, {1442507641=>5}, {1442507641=>6}, {1442507641=>5}, {1442507695=>9}, {1442507695=>9}, {1442507695=>7}, {1442507695=>8}]
How can I make the bracket as plot requires and remove the strange =&gt ?
It seems like this ought to do what you're asking for:
parts = TableName.where(:id => requiredid).map do |r|
sprintf("{%d,%d}", r.received_date, r.value)
end
#data = "[#{parts.join(",")}]"
It's only for your options to manipulate your data:
#data = []
#data = User.where(:id => requiredid).map {|r| #data << "{#{r. received_date}, #{r.value}}"}
First you make #data as array. Than collect the string into array.

Loop through hash in Ruby

My search returns this hash bellow
{"product"=>[{:title=>"It's All About Shoes Barbie Shoe Tree 2010 Hallmark Ornament"}, {:title=>"Iron Lady Bug Key Holder - Hide-A-Key"}]}
here is the loop and the code that generates the hash
id = "B003TM2IDS,B004X75EX4"
ids = id.split(',')
response = []
prod = Hash.new
product = Hash.new
#fetch product title from amazon
for aid in ids do
res = Amazon::Ecs.item_lookup(aid, { :response_group => "ItemAttributes"})
res.items.each do |item|
prod[:title] = item.get("ItemAttributes/Title")
end
# hash
product = {"product" => response.push(prod.dup)}
end
#loop to print the titles - Not working
product.each do |item_prod|
puts item_prod.title
end
I do get the
undefined method `title' for # (NoMethodError)
My question are:
Is the Product hash correct?
Is the loop correct?
I've done this millions of times but some reason I can't see the problem with this
Thanks a lot in advance
Do as below:
product["product"].each do |prod|
puts prod[:title]
end
product["product"].each { |p| puts p[:title] }

How to access the value that is rendered after decoding in rails?

How can i access the year from the json shown below which i fetch from a url and decode using
obj = ActiveSupport::JSON.decode(response.body)
The folloowing is the response i get after decode
{
"educations"=>{"_total"=>1,
"values"=>[
{"id"=>18234534505,
"schoolName"=>"Test",
"startDate"=>{"year"=>2013}
}
]
}
}
How can i access the year? I can able to access the values as
obj['educations']['values']
and it responds as
{"id"=>18234534505, "schoolName"=>"Test", "startDate"=>{"year"=>2013}}
but how can i get the year? please help me.
UPDATE:
how can i add if condition here?
obj["educations"]["values"].each do |value|
#user_education = Education.new("start_date" =>
value['startDate']['year'], "education_id" => value['id'],
"school_name" => value['schoolName'])
end
so here if there is no year then how can i check as you said? and there may also be endDate similar to the startDate so how can i check this?
Just access the key as
obj["educations"]["values"].first["startDate"]["year"]
# above is answer if there is always one array inside `obj["educations"]["values"]`
For multiple arrays's
year = []
obj["educations"]["values"].each do |object|
year << object["startDate"]["year"] if !object["startDate"].blank? and !object["startDate"]["year"].blank?
end
update :
If you want to add attributes to the
#user_education = Education.new
#user_education.start_date = value['startDate']['year'] if !value['startDate'].blank? and !value['startDate']['year'].blank?
#user_education.education_id = value['id'] if !value['id'].blank?
#user_education.school_name = value['schoolName'] if !value['schoolName'].blank?
Similarly for any other attribute..
obj["educations"]["values"].each do |value|
#user_education = Education.new("education_id" => value['id'], "school_name" => value['schoolName'])
#user_education.start_date = value["startDate"]["year"] if !value["startDate"].blank? and !object["startDate"]["year"].blank?
#user_education.save! #To save the object
end

Using a method while looping through an array in ruby

I am using ruby-aaws to return Amazon Products and I want to enter them into my DB. I have created a model Amazonproduct and I have created a method get_amazon_data to return an array with all the product information. When i define the specific element in the array ( e.g. to_a[0] ) and then use ruby-aaws item_attributes method, it returns the name I am searching for and saves it to my DB. I am trying to iterate through the array and still have the item_attributes method work. When i don't define the element, i get this error: undefined method `item_attributes' for #Array:0x7f012cae2d68
Here is the code in my controller.
def create
#arr = Amazonproduct.get_amazon_data( :r ).to_a
#arr.each { |name|
#amazonproduct = Amazonproduct.new(params[:amazonproducts])
#amazonproduct.name = #arr.item_attributes.title.to_s
}
EDIT: Code in my model to see if that helps:
class Amazonproduct < ActiveRecord::Base
def self.get_amazon_data(r)
resp = Amazon::AWS.item_search('GourmetFood', { 'Keywords' => 'Coffee Maker' })
items = resp.item_search_response.items.item
end
end
Thanks for any help/advice.
I'm not familiar with the Amazon API, but I do observe that #arr is an array. Arrays do not usually have methods like item_attributes, so you probably lost track of which object was which somewhere in the coding process. It happens ;)
Try moving that .item_attributes call onto the object that supports that method. Maybe amazonproduct.get_amazon_data(:r), before its being turned into an array with to_a, has that method?
It's not quite clear to me what your classes are doing but to use #each, you can do something like
hash = {}
[['name', 'Macbook'], ['price', 1000]].each do |sub_array|
hash[sub_array[0]] = sub_array[1]
end
which gives you a hash like
{ 'name' => 'Macbook', 'price' => 1000 }
This hash may be easier to work with
#product = Product.new
#product.name = hash[:name]
....
EDIT
Try
def create
#arr = Amazonproduct.get_amazon_data( :r ).to_a
#arr.each do |aws_object|
#amazonproduct = Amazonproduct.new(params[:amazonproducts])
#amazonproduct.name = aws_object.item_attributes.title.to_s
end
end

Resources