Using group_by to find dupe records - ruby-on-rails

I am trying to run the following code:
dupe_groups = Activity.all.group_by { |e| e.non_id_attributes }.select{ |gr| gr.last.size > 1 }
redundant_elements = dupe_groups.map { |group| group.last - [group.last.first] }.flatten
redundant_elements.each(&:destroy)
However, I get the following error:
Activity.find(:all).group_by { |e| e.non_id_attributes }.select{ |gr| gr.last.size > 1 }
NoMethodError: undefined method `last' for #<Hash:0x00000107e505e8>
from (irb):10:in `block in irb_binding'
from (irb):10:in `select'
from (irb):10
from /usr/local/bin/irb:12:in `<main>'
How can I get this fella to work?

When you do a group_by you get a hash, the thing you group by is represented as the keys in the hash so when you select over it you should be doing .select{|key, values| ...} and you can then values.size > 1
Although, when I look at this code, it has a smell to me. What are you actually trying to do?

Related

I am using https://github.com/tyrauber/stock_quote to fetch stock data. However I am getting below mentioned error while doing so

I am new to ruby on rails. :(
while doing a search I am getting StockQuote::NoDataForStockError in StocksController#search ...........................
My model
class Stock < ActiveRecord::Base
def self.find_by_ticker(ticker_symbol)
where(ticker: ticker_symbol).first
end
def self.new_from_lookup(ticker_symbol)
looked_up_stock = StockQuote::Stock.quote(ticker_symbol)
return nil unless looked_up_stock.name
new_stock = new(ticker: looked_up_stock, name: looked_up_stock.name)
new_stock.last_price = new_stock.price
new_stock
end
def price
closing_price = StockQuote::Stock.quote(ticker).close
return "#{closing_price} (closing)" if closing_price
opening_price = StockQuote::Stock.quote(ticker).open
return "#{opening_price (opening)}" if opening_price
"Unavailable"
end
end
Errors I am getting in console while doing a search.
StockQuote::NoDataForStockError: StockQuote::NoDataForStockError
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/stock_quote-1.2.3/lib/stock_q
uote/stock.rb:134:in `parse'
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/stock_quote-1.2.3/lib/stock_q
uote/stock.rb:86:in `block in quote'
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/rest-client-1.6.7/lib/restcli
ent/request.rb:228:in `call'
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/rest-client-1.6.7/lib/restcli
ent/request.rb:228:in `process_result'
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/rest-client-1.6.7/lib/restcli
ent/request.rb:178:in `block in transmit'
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/2.2.0/net/http.rb:853:in `start'
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/rest-client-1.6.7/lib/restcli
ent/request.rb:172:in `transmit'
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/rest-client-1.6.7/lib/restcli
ent/request.rb:64:in `execute'
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/rest-client-1.6.7/lib/restcli
ent/request.rb:33:in `execute'
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/stock_quote-1.2.3/lib/stock_q
uote/stock.rb:84:in `quote'
from C:/Sites/tracker/app/models/stock.rb:19:in `price'
from C:/Sites/tracker/app/models/stock.rb:14:in `new_from_lookup'
from (irb):9
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/railties-4.2.5.1/lib/rails/co
mmands/console.rb:110:in `start'
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/railties-4.2.5.1/lib/rails/co
mmands/console.rb:9:in `start'
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/railties-4.2.5.1/lib/rails/co
mmands/commands_tasks.rb:68:in `console'
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/railties-4.2.5.1/lib/rails/co
mmands/commands_tasks.rb:39:in `run_command!'
from C:/RailsInstaller/Ruby2.2.0/lib/ruby/gems/2.2.0/gems/railties-4.2.5.1/lib/rails/co
mmands.rb:17:in `<top (required)>'
from bin/rails:4:in `require'
If you look at the code for that gem you can see that a StockQuote::NoDataForStockError is returned when the response code is not 200. You'll need to delve into what it doesnt like about the data you are providing. For example you should be able to query the response a bit more and at least determine what url is being sent.
The solution for page interrupting is to use begin rescue blocks every time when we call methods from StockQuote module. In begin part of block use regular call and in rescue part set value to nil and in that case return value 'Unavailable' and similar.begin rescue in Ruby is like try catch in Java. Example:
def price
begin
closing_price = StockQuote::Stock.quote(ticker).close
rescue
closing_price = nil
end
return "#{closing_price} (Closing)" if closing_price
begin
opening_price = StockQuote::Stock.quote(ticker).open
rescue
opening_price = nil
end
return "#{opening_price} (Opening)" if opening_price
'Unavailable'
end

Ruby where clause is returning nil object? ActionView::Template::Error (undefined method `each' for nil:NilClass):

I'm getting the follow error:
ActionView::Template::Error (undefined method `each' for nil:NilClass):
Here is the where clause, the first one works.
def self.unpaid
ARequest.where(:paid_on => nil).in(:status => [ARequest::TRANS_COMPLETE,ARequest::CANCELLED_BY]).gt(:total_owed_to_driver_in_cents => 0).asc(:assigned_driver_id).asc(:timestamp_requested)
end
This does NOT work.
def self.allcall
longtimeago = Time.now - 60.day
yesterday = Time.now - 1.day
ARequest.where(["paid_on >= ? AND paid_on <= ?", longtimeago.beginning_of_day, yesterday.end_of_day]).in(:status => [ARequest::TRANS_COMPLETE,ARequest::CANCELLED_BY]).gt(:total_owed => 0).asc(:assigned_driver_id).asc(:timestamp_requested)
end
The above throws this error:
ActionView::Template::Error (undefined method `each' for nil:NilClass):
CONTROLLER CODE
def allcalls
ensure_root
#calls = ARequest.allcall
end
ROUTE
get "sme/allcalls"
Just try to change
where(["paid_on >= ? AND paid_on <= ?", longtimeago.beginning_of_day, yesterday.end_of_day])
to
where("paid_on >= ? AND paid_on <= ?", longtimeago.beginning_of_day, yesterday.end_of_day)

undefined method `each` for nil:NilClass

I have following code and getting error of "undefined method each' for nil:NilClass"
#loan_ids = params[:moredata].split(",").map { |s| s.to_i }
#loans_ids.each do |number|
puts number
end
Its #loan_ids.each not #loans_ids.each
#loan_ids=params[:moredata].split(",").map{|s| s.to_i }
#loan_ids.each do |number|
puts number
end
You have misspelled it
It's #loan_ids.each not #loans_ids.each. You have a plural "loans" when it's not defined that way.

ruby on rails scopes - ArgumentError: wrong number of arguments(1 for 0)

I'm getting a wrong arguments error when invoking a scope:
Report.start_driver_time(Unit.find(3007),Driver.find(2),3,2013)
scope :start_driver_time, lambda { |unit, driver, month, year|
where("unit_id = ? AND
driver_id = ? AND
extract(MONTH FROM time) = ? AND
extract(YEAR FROM time) = ?",
unit.id, driver.id, month, year)
.order("time asc")
.min(:time)
}
#select(:time) select([:id, :time])
scope :next_driver_time, lambda {|unit, time|
joins(:alerts => {:alert_code => :alert_unit_codes})
.where("reports.unit_id = ? AND
reports.time >= ? AND
alert_unit_codes.name = ?",
unit.id, time, "Seat Belt OFF")
.min(:time)
}
scope :reports_within_driving_period, lambda { |start_time, end_time|
where("unit_id = ? AND
reports.time >= ? AND
reports.time <= ?",
start_time, end_time)
}
stacktrace:
ArgumentError: wrong number of arguments(1 for 0)
from /Users/johnmerlino/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.2.5/lib/active_record/relation/delegation.rb:37:in `min'
from /Users/johnmerlino/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.2.5/lib/active_record/relation/delegation.rb:37:in `method_missing'
from /Users/johnmerlino/Documents/github/XKTrackingSystem/app/models/report.rb:40:in `block in <class:Report>'
from /Users/johnmerlino/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.2.5/lib/active_record/scoping/named.rb:180:in `call'
from /Users/johnmerlino/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.2.5/lib/active_record/scoping/named.rb:180:in `block (2 levels) in scope'
from /Users/johnmerlino/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.2.5/lib/active_record/scoping/default.rb:41:in `block in unscoped'
from /Users/johnmerlino/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.2.5/lib/active_record/relation.rb:241:in `block in scoping'
from /Users/johnmerlino/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.2.5/lib/active_record/scoping.rb:98:in `with_scope'
from /Users/johnmerlino/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.2.5/lib/active_record/relation.rb:241:in `scoping'
from /Users/johnmerlino/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.2.5/lib/active_record/scoping/default.rb:41:in `unscoped'
from /Users/johnmerlino/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.2.5/lib/active_record/scoping/named.rb:180:in `block in scope'
from (irb):1
from /Users/johnmerlino/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.5/lib/rails/commands/console.rb:47:in `start'
from /Users/johnmerlino/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.5/lib/rails/commands/console.rb:8:in `start'
from /Users/johnmerlino/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.5/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'1.9.3p0 :002 > exit
I think you intend to use minimum instead of min? I haven't found a reference to min, so it might be using a different method that uses no parameters.

Why does this named_scope create a NoMethodError?

I don't see where this code is creating this NoMethodFound error, and would really like any helpful suggestions.
Here's the error message:
NoMethodError in UploadsController#create
The relevant parts of my model looks like this:
named_scope :by_name, lambda { |marker_name|
{:conditions => ["marker_name = ?", marker_name]}}
def self.parse_file(file)
FasterCSV.foreach(file.path,:headers=>"first_row", :col_sep=>"\t") do |row|
if $header_row == 1
$markers = {} # define global hash for marker id lookup
$markers_arry = [] # define global array for marker names
get_markers(row)
$header_row = 0
# done with header row; loop back to beginning for first row of actual data
next
end
...
def self.get_markers(row)
offset = 8 # this was determine by trial-&-error
i = 0
for col in row
i += 1
if i < offset
next
end
this_marker = Marker.by_name(row[col])
$markers[row[col]] = this_marker.id # associate the marker_name with its id
$markers_arry[col] = row[col]
end
end
The trace looks like:
> undefined method `by_name' for
> #<Class:0xb6726e40>
> vendor/rails/activerecord/lib/active_record/base.rb:1667:in
> `method_missing'
> app/models/upload.rb:99:in
> `get_markers'
> /usr/lib/ruby/gems/1.8/gems/fastercsv-1.5.4/lib/faster_csv.rb:362:in
> `each'
> /usr/lib/ruby/gems/1.8/gems/fastercsv-1.5.4/lib/faster_csv.rb:362:in
> `each' app/models/upload.rb:91:in
> `get_markers'
> app/models/upload.rb:37:in
> `parse_file'
> /usr/lib/ruby/gems/1.8/gems/fastercsv-1.5.4/lib/faster_csv.rb:1545:in
> `each'
> /usr/lib/ruby/gems/1.8/gems/fastercsv-1.5.4/lib/faster_csv.rb:1048:in
> `foreach'
> /usr/lib/ruby/gems/1.8/gems/fastercsv-1.5.4/lib/faster_csv.rb:1222:in
> `open'
> /usr/lib/ruby/gems/1.8/gems/fastercsv-1.5.4/lib/faster_csv.rb:1047:in
> `foreach' app/models/upload.rb:25:in
> `parse_file'
> app/controllers/uploads_controller.rb:55:in
> `create'
> vendor/rails/actionpack/lib/action_controller/base.rb:1162:in
> `send'
Note that in Rails 3, named_scope has been renamed to scope.
Have you tried doing just "by_name" instead of "Marker.by_name" ?
Also, Rails dynamically generates many similar methods. For instance,
Marker.find_by_name("your_name_here")
... Which ought to work regardless.

Resources