17andLearning
17andLearning

Reputation: 477

Rescue "undefined method 'xyz' for nil:nilClass" errors

I have the following show action:

def show
  @name = params[:id]
  rescue ActiveRecord::RecordNotFound
  redirect_to :action => 'index'     
  @rpm = FedoraRpm.find_by_name(@name, :include => :rpm_comments)
  @page_title = @rpm.name
end

Even though I've added a rescue statement there, it doesn't seem to work and I get this error when I try to view a non existent URL:

undefined method 'name' for nil:NilClass

I know that this might be related to the @page_title variable, but how can I fix this?

Upvotes: 2

Views: 2234

Answers (2)

Vitaliy Yanchuk
Vitaliy Yanchuk

Reputation: 1501

Surely you do. There are 2 reasons:

  1. The rescue statement you use is before the place where error happens, or could happen
  2. You point to special type of error ActiveRecord::RecordNotFound that wil be fired only when you use find method, or adding ! at the end of find_by_name

So you should move rescue line to the bottom of the method, like:

def show
  @name = params[:id]
  @rpm = FedoraRpm.find_by_name!(@name, :include => :rpm_comments)
  @page_title = @rpm.name
rescue ActiveRecord::RecordNotFound
  redirect_to :action => 'index'     
end

Notice I`ve added ! mark to the end of find_by_name, it will fire an exception of record is not found, in your case it would just return nil, so you would hace error when trying to get .name from nil

Upvotes: 2

Simone Carletti
Simone Carletti

Reputation: 176472

@rpm = FedoraRpm.find_by_name(@name, :include => :rpm_comments)

returns nil if unable to find a result. This is probably your case. Then, you attempts to invoke name on a nil object.

If you expect the query to return a nil value, make sure to change your code accordingly.

The rescue statement doesn't make any sense there. If you want to redirect in case of missing record when use

def show
  @name = params[:id]
  @rpm = FedoraRpm.find_by_name!(@name, :include => :rpm_comments)
  @page_title = @rpm.name
rescue ActiveRecord::RecordNotFound
  redirect_to :action => 'index'     
end

Note I used the bang version of the finder.

@rpm = FedoraRpm.find_by_name!(@name, :include => :rpm_comments)

Upvotes: 5

Related Questions