Ruby Undefined method downcase
18,945
When you see "undefined method ...
for nil:NilClass" it means you have a nil
value you're trying to call the method on.
In this case, something like data['name']
is not defined.
To make this more bullet-proof:
data['name'].to_s.downcase.gsub(/\s+/, '')
This converts everything to string to start with. nil.to_s
is an empty string by default, so it's safe.
Author by
charliexx
Updated on July 09, 2022Comments
-
charliexx almost 2 years
I'm getting an exception in the following piece of code. Can someone please tell me what I'm doing wrong, and how I can prevent it?
def self.find_by_data(data = {}) where(name_canonical: data['name'].downcase.gsub(/\s+/, ''), fuel: data['fuel'], trim_canonical: data['trim'].downcase.gsub(/\s+/, ''), year: data['year']).first end
Exception:
/Users/charlie/Documents/WIP/projectx/ar_models.rb:35:in `find_by_data': undefined method `downcase' for nil:NilClass (NoMethodError)ooooooooooooooooooooooooo| ETA: 0:00:00 from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/relation/delegation.rb:36:in `block in find_by_data' from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/associations/collection_proxy.rb:845:in `block in scoping' from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/relation.rb:270:in `scoping' from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/associations/collection_proxy.rb:845:in `scoping' from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/relation/delegation.rb:36:in `find_by_data' from /Users/charlie/Documents/WIP/projectx/ar_models.rb:132:in `create_or_assign_existing' from /Users/charlie/Documents/WIP/projectx/app.rb:230:in `block (2 levels) in work' from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:294:in `with_connection' from /Users/charlie/Documents/WIP/projectx/app.rb:80:in `block in work' from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:319:in `call' from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:319:in `call_with_index' from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:179:in `block (3 levels) in work_in_threads' from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:326:in `with_instrumentation' from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:177:in `block (2 levels) in work_in_threads' from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:171:in `loop' from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:171:in `block in work_in_threads' from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:62:in `block (2 levels) in in_threads'
-
Arup Rakshit over 10 yearswe don't know what your hash
data
contain.. But it is very clear that eitherdata['name']
ordata['trim']
containsnil
. Check the same
-
-
tadman over 10 years
== nil
is supremely ugly. A better alternative is.nil?
but only if that value might befalse
. Even better in this case is:data['name'] ? data['name'].downcase.gsub(...) : ''
-
konsolebox over 10 years@tadman Yet it's a solution. A better one please? Do we have to go after
has_key?
? But wouldn'tnil
still be possible for that and that we have to check again? -
tadman over 10 yearsI've posted my own take that involves
to_s
which forces the value to a string, regardless of if it'snil
or not. 99% of the timex == nil
can be replaced with!x
or in this case, simply reversing the ternary. -
konsolebox over 10 yearsNow that's ugly for me.
-
tadman over 10 yearsIt's the same thing you have, minus
== nil
, reversing the logic. -
konsolebox over 10 yearsAs you said, not having nil could still apply to
false
. Also ato_s
method is a dirty hack.