Using Ruby 1.8.6 / Rails 2.3.2
I am noticing that any method called on any of my ActiveRecord model classes is returning nil
instead of a NoMethodError. Besides annoying, this is breaking the dynamic finders (find_by_name
, find_by_id
, etc.) because they always return nil
even where records exist. Standard classes that don't derive from ActiveRecord::Base aren't affected.
Is there a way to track down what is intercepting method_missing before ActiveRecord::Base?
UPDATE:
After switching to 1.8.7, I have found (thanks to @MichaelKohl) that the will_paginate plugin is handling method_missing first. But will_paginate has been around in our system (unaltered) for quite a while and the culprit must be something later up the chain. Any ideas how to see what comes next in this chain?
UPDATE:
It turned out that there was a gem (annotate-2.4.0) that was monkey patching ActiveRecord::Base#method_missing
as a blank method. Uninstalling the gem solved my problem. Although none of the answers given actually found the problem, the answer by @Yanhao came closest as it only needed a minor tweak to discover the offending aliased method
Try this in the Rails console:
Replacing
MyModel
with an actual model in your app of course. It should tell what class defines themethod_missing
method. If you're using Ruby 1.9 you can even doMyModel.method(:method_missing).source_location
to get the exact file and line.Have you tried
TheModel.method(:method_missing).owner
? I have no Rails console available, but look at this example:As you can see this shows you the closest
method_missing
definition in the ancestors chain.Edit: sorry, didn't take into account your old Ruby version. In that case, go with @aNoble's suggestion, and also look at How to find where a method is defined at runtime? in this context.
You could try this : In rails console
The last line of the output should be the culprit.
I think @Sebi's answer is helpful, but I'd like to improve it like this:
The result is like this:
Use the Ruby debugger, insert a breakpoint before an
ActiveRecord
-call that returnsnil
and start stepping your way through. I think this is superior to all other solutions discussed here, because it's easy to understand what's really going on and gives you a more thorough understanding of the call hierarchy that causes your problem. Apart from that, it's quite an universal skill that helps solving many other problems.