Why does this named_scope create a NoMethodError? - ruby-on-rails

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.

Related

Creating a scope with a query from a method on Ruby on Rails

Im trying to create a scope on a Model at my project, but I want that the query filter the elements basead on a method at my Model.
This is my model:
class Talent < ApplicationRecord
scope :public_profile, -> { Talent.all.select{ |t| t.age > 13 } }
def age
now = Time.now.utc.to_date
now.year - self.birth_date.year - ((now.month > self.birth_date.month ||
(now.month == self.birth_date.month && now.day >= self.birth_date.day)) ? 0 : 1)
end
When I try to run this scope I get the error:
NoMethodError: undefined method `year' for nil:NilClass
from app/models/talent.rb:195:in `age'
from (irb):6:in `block in irb_binding'
from (irb):6
The line 195 its on my method age. So, probably when doing the select, my element is coming nil.
What Im doing wrong here?
Given:
NoMethodError: undefined method `year' for nil:NilClass
And given that you're only calling the method year twice in the age method:
def age
now = Time.now.utc.to_date
now.year - self.birth_date.year - ((now.month > self.birth_date.month ||
(now.month == self.birth_date.month && now.day >= self.birth_date.day)) ? 0 : 1)
end
And given that now is certain not to be nil:
now = Time.now.utc.to_date
It would seem that self.birth_date is returning nil. And, as the error states, nil doesn't have the year method.

Rails 4 chaining scope

I would like to reuse a scope I defined, but it returns an array.
scope :currents, -> { (where('started_at < NOW()') | where('started_at' => nil)) & where('ended_at > NOW()') & where('published_at < NOW()') }
def self.findNextAuctions()
currents.order(ended_at: :asc).limit(3)
end
When I call the function findNextAuctions I get this error:
1) Error:
AuctionTest#test_should_fint_next_auctions:
NoMethodError: undefined method `order' for #<Array:0x007fae5d6e3878>
app/models/auction.rb:13:in `findNextAuctions'
test/models/auction_test.rb:14:in `block in <class:AuctionTest>'
Rails doesn't have an OR statement. You can write SQL directly though so something like
where("(started_at < NOW() or started_at = null) and ended_at > NOW() and published_at < NOW()")

Rails undefined method `+' for nil:NilClass

I have a method 'calc_price' that was working previously, and still works in console, but is now giving me the following error in a browser:
NoMethodError in Quotes#index
undefined method `+' for nil:NilClass
18: Price: $<%= f.calc_price %><br />
app/models/quote.rb:33:in `block in calc_price'
app/models/quote.rb:13:in `calc_price'
app/views/quotes/index.html.erb:18:in `block in _app_views_quotes_index_html_erb__1788058106025144185_70227449765940'
app/views/quotes/index.html.erb:15:in `each'
app/views/quotes/index.html.erb:15:in `_app_views_quotes_index_html_erb__1788058106025144185_70227449765940'
The fact that it still works in console is confusing to me, especially since I didn't change the method at all for it to break. The method:
def calc_price
self.items.each do |item|
pr = if item.amount < 10
item.product.pricerange0
elsif item.amount < 25
item.product.pricerange1
elsif item.amount < 50
item.product.pricerange2
elsif item.amount < 100
item.product.pricerange3
elsif item.amount < 250
item.product.pricerange4
elsif item.amount < 500
item.product.pricerange5
end
screens = 0
sd = item.shirtdesigns.count
pd = item.pantdesigns.count
screens = (sd+pd)
screenprice = (screens*25)
inkprice = ((item.inkcolors-1)*0.5)
newprice = ((pr+inkprice)*item.amount+screenprice)
item.price = newprice
item.save
end
newprice = self.items.sum('price')
self.price = newprice
self.save
return self.price
end
quote controller
def index
#quote = Quote.find(:all)
#myquotes = Quote.find(:all, :conditions => { :user_email => current_user.email })
end
I tried adding screenprice = 0, newprice = 0 and inkprice = 0 to see if that would make a difference but it did not.
If it still works in console does that mean maybe its not the method itself that is broken?
Any help would be greatly appreciated! Thanks
pr is most likely nil. An item with an amount greater than 500 would result in pr being nil in the code above.

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.

Using group_by to find dupe records

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?

Resources