NoMethodError: undefined method '...'
NoMethodError: undefined method '...' means the object you’re calling a method on doesn’t recognize that name — it’s not defined in its class or ancestors.
What It Means
Ruby objects respond to messages (method calls). Every object has a set of methods it can respond to — defined by its class, superclasses, included modules, and singleton methods. When you send a message the object doesn’t understand, Ruby raises NoMethodError. The error includes the method name and the object’s class, giving you both clues to fix it.
Why It Happens
- Calling a method on a variable that unexpectedly holds
nil— the #1 cause. - A typo in the method name —
savevssavorfind_byvsfind_by_. - Calling a private or protected method from outside the class.
- Using an older Ruby version where a method doesn’t yet exist.
- Calling a method on the wrong object type — e.g., calling
.pushon a String instead of an Array. - The method is defined in a module that hasn’t been included or extended.
How to Fix It
Step 1: Find where nil enters your code
Use inspect or p to see the actual value:
def find_user(id)
result = User.where(id: id)
p result # Check what this returns — might be nil
result.name # NoMethodError if result is nil
endStep 2: Use the safe navigation operator
Chain method calls without crashing on nil:
# Instead of this:
user.profile.address.city
# Use this:
user&.profile&.address&.city # Returns nil if any part is nilStep 3: Check method visibility
Private methods can only be called without an explicit receiver:
class Document
private
def format
"formatted"
end
end
doc = Document.new
# doc.format # NoMethodError
doc.send(:format) # Works — but use only in testsStep 4: Verify the method exists in the right module
If you’re mixing in a module, check it’s included:
module Searchable
def search(query)
# ...
end
end
class Product
include Searchable # Without this, search() won't exist on Product
endStep 5: Use respond_to? to guard
if object.respond_to?(:name)
object.name
else
"default name"
endStep 6: Check method_missing if you use dynamic dispatch
If you rely on method_missing, ensure the proxy properly forwards:
def method_missing(name, *args)
if @target.respond_to?(name)
@target.send(name, *args)
else
super # Call super to raise the standard NoMethodError
end
endBuilt by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro