Ruby - NoMethodError (undefined method for nil:NilClass): - ruby-on-rails

I'm having some difficulty trying to figure out what I am doing wrong. My ActiveRecord query is returning nil which I think is causing NoMethodError to be raised.
Here's what I have:
#number_exclude_list = ["1234567890", "2223334545"]
#available_number = UserNumber.where.not(:user_num => #number_exclude_list)
Which returns an empty set of rows:
=> #<ActiveRecord::Relation []>
So, then I have:
if (#available_number.empty?)
inform_user_empty
else
do_my_other_function
But, I get:
`NoMethodError (undefined method 'inform_user_empty' for nil:NilClass)`
I have tried: #available_number.blank? and `#available_number.nil?
And I still get the same NoMethodError. Any ideas on what I am doing wrong here?

The exception text NoMethodError (undefined method 'inform_user_empty' for nil:NilClass) says that is was a call to instance method #inform_user_empty of the nil class'es instance, and since nil has no instance method ruby interpreter throwed that exception. I see the two main reason for it:
self keyword variable has nil value, I believe not in the reason, because you do a call from a controller, as you've said ApplicationController. To make sure that self isn't nil, change the code to the following one:
if #available_number.empty?
p self
self.inform_user_empty
rerun the action, and look at the result.
The exception has been thrown from another place. So you have to specify the full trace log in your post.

Please run the below line in your console:
#available_number = UserNumber.where.not(:user_num => #number_exclude_list)
it returns an ArgumentError: wrong number of arguments (0 for 1+) since it is not the way to check NOT IN condition in Rails activerecord.
Replace it with:
User.where('user_num NOT IN (?)',#number_exclude_list)
and then do:
if #available_number == nil
inform_user_empty
else
do_my_other_function
end
Hoep that will resolve the issue. Please let me know if it really helped you.

Related

NoMethodError (undefined method `<' for nil:NilClass):

This is the error I have received:
NoMethodError (undefined method `<' for nil:NilClass):
app/controllers/concerns/withdraws/withdrawable.rb:20:in `create'
This is the part of the code in question:
def create
#withdraw = model_kls.new(withdraw_params)
#verified = current_user.id_document_verified?
#local_sum = params[:withdraw][:sum]
if !#local_sum
render text: I18n.t('private.withdraws.create.amount_empty_error'), status: 403
return
end
if !#verified && channel.currency_obj.withdraw_limit < #local_sum <<<<<- Here is the error
render text: I18n.t('private.withdraws.create.unverified_withdraw_limit_error', limit: channel.currency_obj.withdraw_limit), status: 403
return
end
That's all my code:
https://github.com/DigitalCoin1/Spero-Exchange
The error in question is in this file:
https://github.com/DigitalCoin1/Spero-Exchange/blob/rebuild-peatio/app/controllers/concerns/withdraws/withdrawable.rb
Thank you very much!!!
Remember, (almost) everything is Ruby is an object... including nil.
Keeping that in mind, consider what happens when you call a method that doesn't exist on nil:
irb(main):001:0> nil.something
Traceback (most recent call last):
2: from /Users/scott/.rbenv/versions/2.5.1/bin/irb:11:in `<main>'
1: from (irb):1
NoMethodError (undefined method `something' for nil:NilClass)
Additionally, in Ruby operators such as >, <, and == are actually method calls. So, for example, an instance of Integer such as 3 has a method defined on it called < and when you call 3 < 4, that calls the method on that instance. This works like that because in Ruby you can omit parentheses when making method calls. For example:
irb(main):001:0> 3 < 4
=> true
irb(main):002:0> 3.<(4)
=> true
So putting these two examples together:
irb(main):014:0> nil < 4
Traceback (most recent call last):
2: from /Users/scott/.rbenv/versions/2.5.1/bin/irb:11:in `<main>'
1: from (irb):14
NoMethodError (undefined method `<' for nil:NilClass)
Now, let's take a look at your code.
You're getting the exception:
NoMethodError (undefined method `<' for nil:NilClass)
On this line:
!#verified && channel.currency_obj.withdraw_limit < #local_sum
Looking at this code, you are only calling < in one place. This means that whatever is to the left of it (channel.currency_obj.withdraw_limit) must be nil.
There are a few ways we can fix this... The best way, (in my opinion) is to make sure that channel.currency_obj can never be nil. I unfortunately don't have enough code to show you exactly how to do that, so let's look at some other options...
We can use Ruby 2.3+'s safe navigation operator (&.) -- but it's a little weird to use with an operator like <.
channel.currency_obj.withdraw_limit&. < #local_sum
Note: in this example the expression will evaluate to nil and because nil is falsey the conditional will return false.
Or, we can just add another expression to our conditional to check for nil:
!#verified && channel.currency_obj.withdraw_limit && channel.currency_obj.withdraw_limit < #local_sum
The error happened when channel.currency_obj.withdraw_limit return nil or #local_sum is nil.
And it can't compare nil value.
You must check #local_sum again, and make sure that it have a value. Or channel.currency_obj.withdraw_limit make sure that it have a value.
But i guess that channel.currency_obj.withdraw_limit return nil.
That your problem.
NoMethodError (undefined method `<' for nil:NilClass):
app/controllers/concerns/withdraws/withdrawable.rb:20:in `create'
This error denotes that it is trying to compare < for a nil value.
Can you please print and check channel.currency_obj.withdraw_limit and #local_sum before the error statement.
To avoid nil errors you can include nil check.
if channel.currency_obj.withdraw_limit != nil and #local_sum != nil

delete_if returning undefined method `include?' for nil:NilClass

Not sure why this is happening, I'm just using the method how I see it here: delete_if
But obviously I'm doing something wrong, just can't tell what.
This is my code:
non_enabled_speeds = ["Expedited", "Standard"]
parsed_rates = [{:service_name=>"Expedited",
:service_code=>"XYZ", :total_price=>800, :currency=>"USD"},
{:service_name=>"Priority", :service_code=>"PYT",
:total_price=>1300, :currency=>"USD"},
{:service_name=>"Standard", :service_code=>"XYZ",
:total_price=>500, :currency=>"USD"}]
non_enabled_speeds.each do |non_enabled_rate|
parsed_rates.delete_if
{|rate| rate[:speed].include?(non_enabled_rate)}
end
I understand that delete_if uses include? under the covers, but I'm not sure why I'm getting this error:
undefined method `include?' for nil:NilClass
Nope, it's not about delete_if. One (or more) of your rate[:speed]s is nil.
{|rate| rate.fetch(:speed, []).include?(non_enabled_rate)}

Rails 3 - NoMethodError: undefined method for nil:NilClass in each Iteration

I'm iterating over an array of instances of a Rails model. Here is my code:
product_details.each do |product_detail|
product_detail.label = Backend::ProductGroup.where(product_group_number: product_detail.product_group).first.label
end
The attribute 'label' from 'product_detail' isn't an attribute from my Rails ActiveRecord model. I added it with attr_accessor in my class definition. I did this, because I wanted to add this attribute dynamically, only when I need to do this. When I ran the code without the 'each' iteration in my rails console it works just fine. But when I execute the above code I get the following error message:
NoMethodError: undefined method 'label' for nil:NilClass
Did I do something obviously wrong?
Many thanks in advance.
You likely have several product_detail items that have no matching product_group. So calling .first on the empty collection returns nil. To get around the error, you can test if the product_group was found before proceeding:
product_details.each do |product_detail|
product_group = Backend::ProductGroup.where(product_group_number: product_detail.product_group).first
product_detail.label = product_group.label if product_group
end
You can also do this more efficiently like so:
group_labels = BackEnd::ProductGroup.
where(product_group_number: product_details.map(&:product_group)).
inject({}){|m, g| m[g.product_group_number] = g.label; m}
product_details.each do |product_detail|
product_detail.label = group_labels[product_detail.product_group]
end
This will result in a single database call to grab all related groups, and put the labels in a keyed hash for easy discovery and assignment.

How to catch an "undefined method `[]' for nil:NilClass" error?

I get an nested array from facebook via omniauth and wanna check if it's empty?/nil?/exists?
the depending line looks like:
unless omniauth['extra']['raw_info']['location']['name'].nil?
This should check if this part of the array is empty or exists.
But always this error was thrown:
undefined method `[]' for nil:NilClass
Do I check arrays wrong?
I tried it with "has_key" "nil?" "empty?" "exists?" "blank?"
But no one of these works!
Please help me, many thanks in advance!
Ideally you should check each nested level to see if it is nil, however, this will also work.
unless (omniauth['extra']['raw_info']['location']['name'] rescue nil).nil?
You can also rescue the NoMethodError specifically.
This error is raised because one of the hash values in the chain of omniauth['extra']['raw_info']['location']['name'].nil? returns nil and it is not the last call ['name'].
If for example omniauth['extra']['raw_info'] returns nil, you're actually trying to call nil['location'] which raises an error in ruby.
You can catch this error simply:
res = omniauth['extra']['raw_info']['location']['name'].nil? rescue true
unless res
#your code here
end
Please notice that the code block above will fill the variable res with true if the ['name'] hash value is nil or any other hash value in the chain returns nil.
A bit late to the party, but, as pointed in this answer, Ruby 2.3.0 introduced a new method called dig, which would return nil if one of the chained keys is nil. Your omniauth auth hash could then be presented as:
omniauth = {
...
"extra"=>{ "raw_info"=>
{ "location"=>"New York",
"gravatar_id"=>"123456789"}}
...
}
omniauth.dig('extra',
'raw_info',
'location',
'name',
'foo',
'bar',
'baz') #<= nil

debugging a ruby on rails error

I'm some what new with ruby on rails, so I'm attempting to debug this error that I'm getting but, from my understanding, is working on the prod code.
The error:
NoMethodError in JoinController#index
undefined method `join_template' for nil:NilClass
/app/controllers/join_controller.rb:5:in `index'
Okay, so line 5 in index is:
elsif current_brand.join_template == 'tms'
So clearly current_brand is nil. The controller is a child class of AppController, so checking that out I see that current_brand is a method:
def current_brand
return #current_brand if defined?(#current_brand)
url_array = request.env['HTTP_HOST'].split('.').reverse
url = url_array[1] << "." << url_array[0]
#current_brand = Brand.find(:first, :conditions => ["url LIKE ?", "%" << url << "%"])
end
It seems that #current_brand is always returned, yet it's continuing to be Nil. What could the problem be?
It may be your query is not returning anything. You can use a debugger, but it's pretty easy to just output #current_brand and see what it evaluates to.
logger.debug(#current_brand)
You must check two things:
Does Rails build the SQL query properly with the url passed in on the last line of that method?
Does the record exist in the brands table? you're not actually checking for that.
Also, passing in the url like that opens you up to a potential SQL injection attack.
You need to rewrite your definition with a rescue or if/else so if you do get a nil element then it won't be a fatal error.
This is your problem:
#current_brand = Brand.find(:first, :conditions => ["url LIKE ?", "%" << url << "%"])
#current_brand is not finding anything so make sure you find something.
#current_brand = Brand.find(:first)
If this fixes the problem then you know it is not finding anything and you will need to change your code that if it returns nil then it doesn't provide the function or it finds a default brand such as what I suggested.

Resources