Rails 3.2 iterate through an array - ruby

I have an array that looks like this:
#shipment_products
[
{"old_qty_shipped"=>"324", "product_id"=>"1", "qty_shipped"=>"12443"}
{"old_qty_shipped"=>"4343423", "product_id"=>"3", "qty_shipped"=>"321344"}
{"old_qty_shipped"=>"23", "product_id"=>"4", "qty_shipped"=>"321"}
]
I want to end up being able to do something like this
#shipment_products.each do |p|
Product.adjust_qtys(p.old_qty_shipped, p.qty_shipped, p.product_id)
end
I'm getting the following error
NoMethodError (undefined method `qty_shipped' for #<ActiveSupport::HashWithIndifferentAccess:0x007f>)
The array is not quite in the right format to do this. I need to find a way to be able to iterate through the key/values and extract the attributes so I can call the method I created in the model. Any ideas?

Check following code.
#shipment_products = [ {"old_qty_shipped"=>"324", "product_id"=>"1", "qty_shipped"=>"12443"}, {"old_qty_shipped"=>"4343423", "product_id"=>"3", "qty_shipped"=>"321344"} , {"old_qty_shipped"=>"23", "product_id"=>"4", "qty_shipped"=>"321"}]
#shipment_products.each do |p|
Product.adjust_qtys(p['old_qty_shipped'], p['qty_shipped'], p['product_id'])
end

Related

Redis-objects Ruby gem, how to retrieve Redis list and iterate?

I'm trying to use redis-objects Ruby gem to store some Redis data in lists.
I am able to create a list by following the example in the documentation.
I am able to find the list from Redis using lrange. Not sure if that is the best way, I couldn't find a method provided by redis-objects.
Initially when I iterate the elements in the list I get the elements in the form of Hashes.
However after I get the list using lrange those are not hashes and I cannot access the data.
What would be the appropriate way to find the list and get the items in hash form?
You can see the code below and the outputs from the console.
#list = Redis::List.new('list_name', :marshal => true)
#list << {:name => "Nate", :city => "San Diego"}
#list.each do |el|
puts el
puts el.class
puts "#{el[:name]} lives in #{el[:city]}"
end
redis = Redis.current
#list = redis.lrange("list_name", 0, -1)
#list.each do |el|
puts el
puts el.class
puts "#{el[:name]} lives in #{el[:city]}"
end
Each of the puts:
{:name=>"Nate", :city=>"San Diego"}
Hash
Nate lives in San Diego
{: nameI" Nate:ET: cityI"San Diego;T
String
Completed 500 Internal Server Error in 349ms
TypeError - no implicit conversion of Symbol into Integer:
Right. The text below, from the Gem documentation explains it!
There is a Ruby class that maps to each Redis type, with methods for
each Redis API command. Note that calling new does not imply it's
actually a "new" value - it just creates a mapping between that Ruby
object and the corresponding Redis data structure, which may already
exist on the redis-server.
So I don't need to use lrange to get to the list. Using Redis::List.new('list_name', :marshal => true) will get me a handle to the list. Then I can iterate, add or remove items from the list.
Reading is helpful...

I need help getting the filters to work with soundcloud api in Ruby

Whenever I add the value of ":limit", ":offset", and ":linked_partitioning => 1" to my api call the filters seem to stop working. How can I get them to work while still getting ?
page_size = 600
tracks = client.get('/tracks', :q => 'music', :limit => page_size, :offset => 200, :linked_partitioning => 1)
tracks.each {|t| puts t.title}
This is the error I get:
If I replace "tracks.each {|t| puts t.title}..." with just..
puts tracks
or..
puts tracks.next_href
I'll get the results, but with NO FILTERS.. if I use any filters like
tracks.each {|t| puts t.id}
or any other one it'll get a method error like before...any ideas?
What I'm trying to get as a result is being able to get tracks by a filter and then be able to get the next page of results using the same filter and so on. Please help. Thanks. :)
If I understand what youre asking I think youre not diving deep enough into the object Soundcloud returns. With your no method error, its saying that you are trying to call .title on an array like this, [some info].title. You might have to step down another level in the data structure. I had a lot of issues with the linked_partitioning, try removing that and iterating though the array like you have been doing. If you get the results youre looking for I would try double iterating through the object.
Hope this helps

Twitter API - Ruby Twitter Gem

How can I access Twitter::Cursor hash values returned by the Twitter API?
I am following the Jumpstartlab Microblogger tutorial for using the Twitter gem via the jumpstart_auth gem.
I am on iteration 4 step 1. I can return a friends object with the following code:
def friends_last_tweets
friends = client.friends
puts friends
end
=> Twitter::Cursor:0x00000104051928
However, the example account, 'client' in this case, has two 'friends' not just one so why does it only return one object? I thought maybe that object is the array or arrays with all of the friends accordingly in hash values within, thus use [] to access, but this returns "undefined method for Twitter::Cursor". I run each on the Twitter::Cursor object and it returns two fixnums:
def friends_last_tweets
friends = client.friends
friends.each { |f| puts f }
end
=> 18908095
108528349
So surely these numbers must represent each 'friend object' within the Twitter::Cursor object me thinks. I need to access the key/value pairs within that object, yet my attempted hash accessing results in undefined method or variable.
In case it's version issue related, I'm using Twitter5.11.0 and Jumpstart_auth 0.6.0.
those answers didn't helped me to get the last message (maybe the API changed in the meantime), that's how I finally did it:
def everyones_last_tweet
puts "\n\n here are the latest tweets of your friends:"
friends = #client.friends.collect { |f| #client.user(f) }
friends.each do |friend|
puts "\n\n#{friend.screen_name} wrote: \n\t #{friend.status.text}"
end
return ""
end
I'm not happy with that return string though
Access the 'friends' object in the same way you accessed the 'followers' object earlier in the tutorial in order to get a list of your followers' screen names.
To get an array of followers' screen names:
screen_names = #client.followers.collect {|f| #client.user(f).screen_name }
To get an array of friends' screen names:
screen_names = #client.friends.collect {|f| #client.user(f).screen_name }
To get the last tweet of a friend, you can use the object_id's you posted above, as:
last_tweet = #client.user(object_id).status.tweet
I hope this helps. I was caught on this issue for a while too.

Koala - how to work with the Koala::Facebook::GraphCollection object?

Koala::Facebook::GraphCollection
by using the search method on the Koala API object, I get a lot of results that I put in a #results variable.
How do I select data from it? for instance, let's take "names"?
using:
results.select{ |l| l[/"name"/] }.each
but it does not work...
the content of the results is like:
{"id"=>"1000000000000", "from"=>{"name"=>"Name Lastname\u0161", "id"=>"1000000000000"}, "message"=> ...
This is just a hash.
Isn't it just results["from"]["name"]?

How to parse SOAP response from ruby client?

I am learning Ruby and I have written the following code to find out how to consume SOAP services:
require 'soap/wsdlDriver'
wsdl="http://www.abundanttech.com/webservices/deadoralive/deadoralive.wsdl"
service=SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver
weather=service.getTodaysBirthdays('1/26/2010')
The response that I get back is:
#<SOAP::Mapping::Object:0x80ac3714
{http://www.abundanttech.com/webservices/deadoralive} getTodaysBirthdaysResult=#<SOAP::Mapping::Object:0x80ac34a8
{http://www.w3.org/2001/XMLSchema}schema=#<SOAP::Mapping::Object:0x80ac3214
{http://www.w3.org/2001/XMLSchema}element=#<SOAP::Mapping::Object:0x80ac2f6c
{http://www.w3.org/2001/XMLSchema}complexType=#<SOAP::Mapping::Object:0x80ac2cc4
{http://www.w3.org/2001/XMLSchema}choice=#<SOAP::Mapping::Object:0x80ac2a1c
{http://www.w3.org/2001/XMLSchema}element=#<SOAP::Mapping::Object:0x80ac2774
{http://www.w3.org/2001/XMLSchema}complexType=#<SOAP::Mapping::Object:0x80ac24cc
{http://www.w3.org/2001/XMLSchema}sequence=#<SOAP::Mapping::Object:0x80ac2224
{http://www.w3.org/2001/XMLSchema}element=[#<SOAP::Mapping::Object:0x80ac1f7c>,
#<SOAP::Mapping::Object:0x80ac13ec>,
#<SOAP::Mapping::Object:0x80ac0a28>,
#<SOAP::Mapping::Object:0x80ac0078>,
#<SOAP::Mapping::Object:0x80abf6c8>,
#<SOAP::Mapping::Object:0x80abed18>]
>>>>>>> {urn:schemas-microsoft-com:xml-diffgram-v1}diffgram=#<SOAP::Mapping::Object:0x80abe6c4
{}NewDataSet=#<SOAP::Mapping::Object:0x80ac1220
{}Table=[#<SOAP::Mapping::Object:0x80ac75e4
{}FullName="Cully, Zara"
{}BirthDate="01/26/1892"
{}DeathDate="02/28/1979"
{}Age="(87)"
{}KnownFor="The Jeffersons"
{}DeadOrAlive="Dead">,
#<SOAP::Mapping::Object:0x80b778f4
{}FullName="Feiffer, Jules"
{}BirthDate="01/26/1929"
{}DeathDate=#<SOAP::Mapping::Object:0x80c7eaf4>
{}Age="81"
{}KnownFor="Cartoonists"
{}DeadOrAlive="Alive">]>>>>
I am having a great deal of difficulty figuring out how to parse and show the returned information in a nice table, or even just how to loop through the records and have access to each element (ie. FullName,Age,etc). I went through the whole "getTodaysBirthdaysResult.methods - Object.new.methods" and kept working down to try and work out how to access the elements, but then I get to the array and I got lost.
Any help that can be offered would be appreciated.
If you're going to parse the XML anyway, you might as well skip SOAP4r and go with Handsoap. Disclaimer: I'm one of the authors of Handsoap.
An example implementation:
# wsdl: http://www.abundanttech.com/webservices/deadoralive/deadoralive.wsdl
DEADORALIVE_SERVICE_ENDPOINT = {
:uri => 'http://www.abundanttech.com/WebServices/DeadOrAlive/DeadOrAlive.asmx',
:version => 1
}
class DeadoraliveService < Handsoap::Service
endpoint DEADORALIVE_SERVICE_ENDPOINT
def on_create_document(doc)
# register namespaces for the request
doc.alias 'tns', 'http://www.abundanttech.com/webservices/deadoralive'
end
def on_response_document(doc)
# register namespaces for the response
doc.add_namespace 'ns', 'http://www.abundanttech.com/webservices/deadoralive'
end
# public methods
def get_todays_birthdays
soap_action = 'http://www.abundanttech.com/webservices/deadoralive/getTodaysBirthdays'
response = invoke('tns:getTodaysBirthdays', soap_action)
(response/"//NewDataSet/Table").map do |table|
{
:full_name => (table/"FullName").to_s,
:birth_date => Date.strptime((table/"BirthDate").to_s, "%m/%d/%Y"),
:death_date => Date.strptime((table/"DeathDate").to_s, "%m/%d/%Y"),
:age => (table/"Age").to_s.gsub(/^\(([\d]+)\)$/, '\1').to_i,
:known_for => (table/"KnownFor").to_s,
:alive? => (table/"DeadOrAlive").to_s == "Alive"
}
end
end
end
Usage:
DeadoraliveService.get_todays_birthdays
SOAP4R always returns a SOAP::Mapping::Object which is sometimes a bit difficult to work with unless you are just getting the hash values that you can access using hash notation like so
weather['fullName']
However, it does not work when you have an array of hashes. A work around is to get the result in xml format instead of SOAP::Mapping::Object. To do that I will modify your code as
require 'soap/wsdlDriver'
wsdl="http://www.abundanttech.com/webservices/deadoralive/deadoralive.wsdl"
service=SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver
service.return_response_as_xml = true
weather=service.getTodaysBirthdays('1/26/2010')
Now the above would give you an xml response which you can parse using nokogiri or REXML. Here is the example using REXML
require 'rexml/document'
rexml = REXML::Document.new(weather)
birthdays = nil
rexml.each_recursive {|element| birthdays = element if element.name == 'getTodaysBirthdaysResult'}
birthdays.each_recursive{|element| puts "#{element.name} = #{element.text}" if element.text}
This will print out all elements that have any text.
So once you have created an xml document you can pretty much do anything depending upon the methods the library you choose has ie. REXML or Nokogiri
Well, Here's my suggestion.
The issue is, you have to snag the right part of the result, one that is something you can actually iterator over. Unfortunately, all the inspecting in the world won't help you because it's a huge blob of unreadable text.
What I do is this:
File.open('myresult.yaml', 'w') {|f| f.write(result.to_yaml) }
This will be a much more human readable format. What you are probably looking for is something like this:
--- !ruby/object:SOAP::Mapping::Object
__xmlattr: {}
__xmlele:
- - &id024 !ruby/object:XSD::QName
name: ListAddressBooksResult <-- Hash name, so it's resul["ListAddressBooksResult"]
namespace: http://apiconnector.com
source:
- !ruby/object:SOAP::Mapping::Object
__xmlattr: {}
__xmlele:
- - &id023 !ruby/object:XSD::QName
name: APIAddressBook <-- this bastard is enumerable :) YAY! so it's result["ListAddressBooksResult"]["APIAddressBook"].each
namespace: http://apiconnector.com
source:
- - !ruby/object:SOAP::Mapping::Object
The above is a result from DotMailer's API, which I spent the last hour trying to figure out how to enumerate over the results. The above is the technique I used to figure out what the heck is going on. I think it beats using REXML etc this way, I could do something like this:
result['ListAddressBooksResult']['APIAddressBook'].each {|book| puts book["Name"]}
Well, I hope this helps anyone else who is looking.
/jason

Resources