How to combine combine any_of with between in Mongoid 4? - ruby

I have read in this SO post this you can combine any_of with between like this:
webshop = Webshop.first
webshop.orders.any_of(
webshop.orders.between(:datetime_pending, [Time.zone.now-7.days, Time.zone.now]).selector, # An error is raised here.
webshop.orders.between(:datetime, [Time.zone.now-7.days, Time.zone.now]).selector
)
But When trying this query, using Mongoid 4, I am getting the error:
ArgumentError: wrong number of arguments (2 for 0..1).
/Users/christoffer/project/vendor/gems/ruby/2.0.0/gems/origin-1.1.0/lib/origin/selectable.rb:63:in `between'
/Users/christoffer/project/vendor/gems/ruby/2.0.0/bundler/gems/mongoid-b91705b0ded8/lib/mongoid/relations/referenced/many.rb:413:in `block in method_missing'
/Users/christoffer/project/vendor/gems/ruby/2.0.0/bundler/gems/mongoid-b91705b0ded8/lib/mongoid/scopable.rb:238:in `with_scope'
/Users/christoffer/project/vendor/gems/ruby/2.0.0/bundler/gems/mongoid-b91705b0ded8/lib/mongoid/relations/referenced/many.rb:412:in `method_missing'
What am I missing here?

According to the documentation Queryable#between takes a hash (a key with a range value).
Have you tried passing that instead of an array?
webshop = Webshop.first
now = Time.zone.now
seven_days = now - 7.days
webshop_orders = webshop.orders
webshop_orders.any_of(
webshop_orders.between(datetime_pending: seven_days..now).selector,
webshop_orders.between(datetime: seven_days..now).selector
)

Related

`*': negative argument (ArgumentError) Ruby

I keep getting this negative argument error when running this code in the Codewars IDE. It runs fine in terminal but in Codewars it both passes the test and runs this error message simultaneously.
STDERR
main.rb:5:in `*': negative argument (ArgumentError)
from main.rb:5:in `maskify'
from main.rb:9:in `<main>'
The code is
def maskify(cc)
x = cc.to_s
y = "#" * (x.length - 4)
return y + x.slice(-4..-1)
end
I'm new to Ruby but I've not heard anywhere that it has a problem with negative numbers being used in .slice. Am I missing something here? Thanks.
You're not considering cases when cc is shorter than 4 symbols.
And expression "#" * (x.length - 4) raises the error because you can't multiply a string by a negative number.
Try to use Array#max method to handle this:
"#" * [x.length - 4, 0].max

SoftLayer API call getVirtualGuests is significantly slower than in the past

I have a basic ruby program I've been using for several months now that retrieves hardware and virtualguest machine details for my account. Up until roughly 3 days ago this always ran fine and relatively fast. Since then it often crashes and/or the virtualguest retrieval takes 20-30 times longer than it has in the past. What could be the issue here? The crash stack is not very informative of the problem.
Program:
require 'rubygems'
require 'softlayer_api'
require 'pp'
client = SoftLayer::Client.new(:username => user, :api_key => api_key, :timeout => 999999)
account = client['Account'].object_mask("mask[virtualGuestCount,hardwareCount]").getObject()
virtual_machines_count = account["virtualGuestCount"]
bare_metal_machines_count = account["hardwareCount"]
bare_metal_machines_count_index = 0
virtual_machines_count_index = 0
for i in 0..(bare_metal_machines_count/10.0).ceil - 1
list_of_baremetal_machines = client['Account'].result_limit(i*10,10).object_mask("mask[id, hostname, fullyQualifiedDomainName, provisionDate, datacenter[name], billingItem[recurringFee, associatedChildren[recurringFee], orderItem[description, order[userRecord[username], id]]], operatingSystem[id, softwareLicense[id, softwareDescription[longDescription]]], tagReferences[tagId, tag[name]], primaryIpAddress, primaryBackendIpAddress]").getHardware
for x in 0..list_of_baremetal_machines.length - 1
bare_metal_machines_count_index = bare_metal_machines_count_index + 1
if bare_metal_machines_count_index == bare_metal_machines_count
pp("Finished retrieving " + bare_metal_machines_count.to_s + " bare metal machines")
end
end
end
for i in 0..(virtual_machines_count/10.0).ceil - 1
list_of_virtual_machines = client['Account'].result_limit(i*10,10).object_mask("mask[id, hostname, fullyQualifiedDomainName, provisionDate, datacenter[name], billingItem[recurringFee, associatedChildren[recurringFee], orderItem[description, order[userRecord[username], id]]], operatingSystem[id, softwareLicense[id, softwareDescription[longDescription]]], tagReferences[tagId, tag[name]], primaryIpAddress, primaryBackendIpAddress]").getVirtualGuests
for x in 0..list_of_virtual_machines.length - 1
virtual_machines_count_index = virtual_machines_count_index + 1
if virtual_machines_count_index == virtual_machines_count
pp("Finished retrieving " + virtual_machines_count.to_s + " virtual machines")
end
end
end
The crash looks like (the process.rb line 552 contains the getVirtualGuests call):
/opt/cds/ruby/lib/ruby/2.1.0/xmlrpc/client.rb:271:in `call': An error has occurred while processing your request. Please try again later. (XMLRPC::FaultException)
from /opt/cds/ruby/gems/gems/softlayer_api-3.1.0/lib/softlayer/Service.rb:267:in `call_softlayer_api_with_params'
from /opt/cds/ruby/gems/gems/softlayer_api-3.1.0/lib/softlayer/APIParameterFilter.rb:194:in `method_missing'
from /home/dashadmin/manas/cds-health-dashboard-sensu/lib/sensu/server/process.rb:552:in `block (5 levels) in retrieve_softlayer_inventory_information'
from /opt/cds/ruby/lib/ruby/gems/2.1.0/gems/activesupport-4.2.4/lib/active_support/core_ext/range/each.rb:7:in `each'
from /opt/cds/ruby/lib/ruby/gems/2.1.0/gems/activesupport-4.2.4/lib/active_support/core_ext/range/each.rb:7:in `each_with_time_with_zone'
from /home/dashadmin/manas/cds-health-dashboard-sensu/lib/sensu/server/process.rb:551:in `block (4 levels) in retrieve_softlayer_inventory_information'
from /home/dashadmin/manas/cds-health-dashboard-sensu/lib/sensu/server/process.rb:511:in `each'
from /home/dashadmin/manas/cds-health-dashboard-sensu/lib/sensu/server/process.rb:511:in `block (3 levels) in retrieve_softlayer_inventory_information'
from /opt/cds/ruby/gems/gems/sensu-em-2.5.1/lib/eventmachine.rb:1054:in `call'
from /opt/cds/ruby/gems/gems/sensu-em-2.5.1/lib/eventmachine.rb:1054:in `block in spawn_threadpool'
Thank you in advance for any help.
The cause of this exception could be due to the amount of data that is attempting to be retrieved at once.
As first suggestion I would tell you, that you use “result limits” in your script. But I can see that you are using this. In that case, you may reduce the values of your result limits.
Other reason could be the query generated from that “object masks” is too intensive and is causing the failures. In that case it is recommended that you please reduce the values in the “object masks”, maybe splitting the retrieval of all those properties into multiple calls and additionally adding a cool down period in the iteration of their virtual guests.
This is pseudo code what I trying to explain:
for x in myVsis:
vsiId = myVsis.id
tempVsiObject1 = getVsi('[property1,property2, property3, property4]') // Call 1 with reduced properties in the mask
tempVsiObject2 = getVsi('[property5, property6, property7 ]') // Call 2 with reduced properties in the mask
tempVsiObject3 = getVsi('[property8[property9[property10[property11]]]]') // Call 3 with reduced properties in the mask
vsi = merge_objects(tempVsiObject1, tempVsiObject2, tempVsiObject3)
sleep(1) // cool down 1 second before moving to the next VSI
I hope this alternative help you, where the result will have in lighter queries each time.

Twitter id_str undefined method #map error in Ruby

I am trying to map an enumerator coming the the Twitter API. I can successfully map the entire enumerable using test.map(&:attrs) and I can map specific fields however when I try to map the id_str field I get a undefined method error. I can't figure out if my syntax is off or if there are other considerations.
Below is my sample code and output:
print "original output\n"
print test.map(&:attrs)
print "\n\nmap a few fields\n"
print test.map { |e| { id: e.id,
name: e.name,
screen_name: e.screen_name
}}
print "\n\nid_str seems to return a undefined method\n"
print test.map { |e| { id: e.id,
id_str: e.id_str,
name: e.name,
screen_name: e.screen_name
}}
Generates the following output:
original output
[{:id=>78194111, :id_str=>"78194111", :name=>"Chelsea Peretti", :screen_name=>"ChelseaVPeretti", :location=>"Los Angeles", :description=>"One of the greats!", :url=>"http://t.co/3rRz8qGpeW", :entities=>{:url=>{:urls=>[{:url=>"http://t.co/3rRz8qGpeW", :expanded_url=>"http://www.chelseaperetti.com", :
display_url=>"chelseaperetti.com", :indices=>[0, 22]}]}, :description=>{:urls=>[]}}, :protected=>false, :followers_count=>249943, :friends_count=>740, :listed_count=>4277, :created_at=>"Tue Sep 29 02:35:35 +0000 2009", :favourites_count=>33016, :utc_offset=>-28800, :time_zone=>"Pacific Time (US & Ca
nada)", :geo_enabled=>true, :verified=>true, :statuses_count=>14958, :lang=>"en", :status=>{:created_at=>"Mon Dec 09 00:40:48 +0000 2013", :id=>409845047744409600, :id_str=>"409845047744409600", :text=>"Really looking forward to spending half my life in an apple store", :source=>"<a href=\"http://tw
itter.com/download/iphone\" rel=\"nofollow\">Twitter for iPhone</a>", :truncated=>false, :in_reply_to_status_id=>nil, :in_reply_to_status_id_str=>nil, :in_reply_to_user_id=>nil, :in_reply_to_user_id_str=>nil, :in_reply_to_screen_name=>nil, :geo=>nil, :coordinates=>nil, :place=>nil, :contributors=>ni
l, :retweet_count=>13, :favorite_count=>77, :entities=>{:hashtags=>[], :symbols=>[], :urls=>[], :user_mentions=>[]}, :favorited=>false, :retweeted=>false, :lang=>"en"}, :contributors_enabled=>false, :is_translator=>false, :profile_background_color=>"022330", :profile_background_image_url=>"http://a0
.twimg.com/profile_background_images/777102099/405580aee5a6a6d3f4d608b5bc488149.jpeg", :profile_background_image_url_https=>"https://si0.twimg.com/profile_background_images/777102099/405580aee5a6a6d3f4d608b5bc488149.jpeg", :profile_background_tile=>true, :profile_image_url=>"http://pbs.twimg.com/pro
file_images/378800000812827132/fe8566998e61c0f3e1275af4953a22e9_normal.jpeg", :profile_image_url_https=>"https://pbs.twimg.com/profile_images/378800000812827132/fe8566998e61c0f3e1275af4953a22e9_normal.jpeg", :profile_banner_url=>"https://pbs.twimg.com/profile_banners/78194111/1382904580", :profile_l
ink_color=>"0084B4", :profile_sidebar_border_color=>"FFFFFF", :profile_sidebar_fill_color=>"C0DFEC", :profile_text_color=>"333333", :profile_use_background_image=>true, :default_profile=>false, :default_profile_image=>false, :following=>false, :follow_request_sent=>false, :notifications=>false}]
map a few fields
[{:id=>78194111, :name=>"Chelsea Peretti", :screen_name=>"ChelseaVPeretti"}]
id_str seems to return a undefined method
C:/RailsInstaller/AppCode/first attempt at graph.rb:142:in `block in <main>': undefined method `id_str' for #<Twitter::User:0x2b602f0> (NoMethodError)
from C:/RailsInstaller/AppCode/first attempt at graph.rb:141:in `map'
from C:/RailsInstaller/AppCode/first attempt at graph.rb:141:in `<main>'
Pretty new to playing with the Twitter API in Ruby myself, but it turns out that id_str isn't a method on the Ruby Twitter::User objects you're trying to enumerate over. Running a quick check on a particular one, say, test.first.methods will confirm this.
This means you can't access id_str with dot notation. It is however a key to the hashes returned by test.map(&:attrs) so you could amend your above code by doing this:
print test.map { |e| { id: e.attrs[:id],
id_str: e.attrs[:id_str],
name: e.attrs[:name],
screen_name: e.attrs[:screen_name]
}}
If you are dead set on using dot notation, you could easily convert each hash object into an OpenStruct like this:
friends = test.map { |f| OpenStruct.new(f.attrs) }
Then you could simply do friends.map(&:id_str).
I think the confusion lies in your sample code above. In the first line, your output is an array of hashes. But what you are mapping over is an array of Twitter::User objects. The former has id_str as a key, but the latter does not have such a method.

Imputing floots into Watirs text field

I am trying to imput data from an array into a web site, however i am getting an error. I beleive the error means that I can't put floots into text fields, so i I changed the floot into a string. But again it did not work. I have only included the part of the code that I felt was relevant.
Blockquote
eee = Watir::Browser.new
eee.goto(fulllink)
eee.text_field(:name => "txtAttr").set Headings[j]
eee.wait
p = j + 1
strings = body.at(0).at(p)
String (strings)
eee.text_field(:name => "txtValue").set strings
eee.wait
eee.link(:index => 4).click
eee.wait
eee.close
end
i += 1
C:\Users\Pure.itloaner1-12\Google Drive\ruby>ruby ExST.rb
hello world
Alpha Numeric Unit #
tables filled
200.0
C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.0.0/lib/watir-classic/input_
elements.rb:356:in `characters_in': undefined method `each_char' for 200.0:Float
(NoMethodError)
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.0.0/lib/watir-c
lassic/input_elements.rb:337:in `type_by_character'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/watir-classic-3.0.0/lib/watir-c
lassic/input_elements.rb:299:in `set'
from ExST.rb:92:in `<main>'
try if changing String(strings) to strings = String(strings) works.

"PGError: no connection to the server" while trying to create or save

Ruby 1.9.1 + ActiveRecord 2.3.5 + Postgres 8.3.7
Here is a rough sketch of my code. Ignore any obvious syntax details left out. The model below inherits from ActiveRecord::Base connected to a Postgres 8.3.7 database via ActiveRecord 2.3.5.
class TableA
has_many :tableB
end
class TableB
belongs_to :tableA
has_many :tableC
end
class TableC
belongs_to :tableB
has_many :tableD
end
class TableD
belongs_to :tableC
has_many :tableE
end
class TableE
belongs_to :tableD
end
# Note that tableA has fids that are referenced in tableE but is not part of this model
#
# Later in the script, in the same global scope, I want to add entries to these tables if
# I cannot find what I need. Bear in mind that this part betrays much Ruby noobiness.
toAdd.each do |widget|
add_tableA = TableA.find_by_sql().first # assumes I will get one back based on earlier sanity checks
add_tableB = TableB.find_by_sql().first
if (add_tableB == nil)
new_tableB = TableB.new( # value assignments )
new_tableB.save
add_tableB = TableB.find_by_sql().first
end
add_tableC = TableC.find_by_sql().first
if (add_tableC == nil)
new_tableC = TableC.new( # value assignments )
new_tableC.save
add_tableC = TableC.find_by_sql().first
end
add_tableD = TableD.find_by_sql().first
if (add_tableD == nil)
new_tableD = TableD.new( # value assignments )
new_tableD.save
add_tableD = TableD.find_by_sql().first
end
# I step into TableA again because items in TableE are linked to items in TableA, but they are
# distinct from the "high level" item I grabbed from TableA earlier.
add_tableA = TableA.find_by_sql().first
if (add_tableA == nil)
new_tableA = TableA.new( # value assignments )
new_tableA.save
add_tableA = TableA.find_by_sql().first
end
# Now that I have a TableA id to put into TableE, just create TableE row because I know this
# does not exist yet.
new_tableE = TableE.new( # value assignments ) # again, this is assumed to be new based on earlier checks
new_tableE.save
end
What always happens is I get the following stack trace:
/...gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract_adapter.rb:219:in `rescue in log': PGError: no connection to the server (ActiveRecord::StatementInvalid)
: ROLLBACK
from .../gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract_adapter.rb:202:in `log'
from .../gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/connection_adapters/postgresql_adapter.rb:550:in `execute'
from .../gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/connection_adapters/postgresql_adapter.rb:576:in `rollback_db_transaction'
from .../gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/database_statements.rb:143:in `rescue in transaction'
from .../gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/database_statements.rb:125:in `transaction'
from .../gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/transactions.rb:182:in `transaction'
from .../gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/transactions.rb:200:in `block in save_with_transactions!'
from .../gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
from .../gems/activerecord-2.3.5/lib/active_record/transactions.rb:200:in `save_with_transactions!'
.... regardless if I'm calling save, save!, or doing a create instead of new and save.
strace reveals that I can only get one BEGIN..INSERT..COMMIT transaction to work for each run of this. Any subsequent attempts to INSERT within a transaction either in the same run of the loop or the next one ends with the connection being dropped before a COMMIT is sent. Clearly, I'm doing something wrong here with how I'm stepping into the ActiveRecord model.
I see the following strace only just before the first successful INSERT statement is set up. Is there something in ActiveRecord that allows me to preserve this as I step through tables, or am I simply Doing It Wrong?
rt_sigaction(SIGPIPE, {0x1, [], SA_RESTORER|SA_RESTART, 0x3876c0eb10}, {0x4b2ff0, [], SA_RESTORER|SA_RESTART, 0x3876c0eb10}, 8) = 0
sendto(3, "Q\0\0\2e SELECT attr.attna"..., 614, 0, NULL, 0) = 614
rt_sigaction(SIGPIPE, {0x4b2ff0, [], SA_RESTORER|SA_RESTART, 0x3876c0eb10}, {0x1, [], SA_RESTORER|SA_RESTART, 0x3876c0eb10}, 8) = 0
poll([{fd=3, events=POLLIN|POLLERR}], 1, -1) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "T\0\0\0:\0\2attname\0\0\0\4\341\0\2\0\0\0\23\0#\377\377\377\377\0"..., 16384, 0, NULL, NULL) = 541
Any help here is greatly appreciated.
Thanks everyone. I apologize for taking anyone's time in trying to fix this. This instance of postgres depends upon a second process to run to handle pushing trigger events out to other processes. That process was not running, so the database server booted after the first committed INSERT. It's a custom in-house kind of thing.

Resources