问题描述
使用 Ruby 1.8.6/Rails 2.3.2
Using Ruby 1.8.6 / Rails 2.3.2
我注意到在我的任何 ActiveRecord 模型类上调用的任何方法都返回 nil
而不是 NoMethodError.除了烦人之外,这破坏了动态查找器(find_by_name
、find_by_id
等),因为它们总是返回 nil
,即使存在记录.不从 ActiveRecord::Base 派生的标准类不受影响.
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.
有没有办法在 ActiveRecord::Base 之前追踪拦截 method_missing 的是什么?
Is there a way to track down what is intercepting method_missing before ActiveRecord::Base?
更新:
切换到 1.8.7 后,我发现(感谢 @MichaelKohl)will_paginate 插件首先处理 method_missing.但是 will_paginate 已经在我们的系统中(未更改)存在了很长一段时间,罪魁祸首一定是链上的某些东西.任何想法如何查看此链中接下来会发生什么?
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?
更新:
事实证明,有一个 gem (annotate-2.4.0) 将 ActiveRecord::Base#method_missing
修补为一个空白方法.卸载 gem 解决了我的问题.尽管给出的答案实际上都没有发现问题,但@Yanhao 的答案最接近,因为它只需要稍作调整即可发现有问题的别名方法
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
推荐答案
我认为@Sebi 的回答很有帮助,但我想像这样改进它:
I think @Sebi's answer is helpful, but I'd like to improve it like this:
set_trace_func proc { |event, file, line, id, binding, classname|
printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname if id.to_s == 'method_missing'
}
结果是这样的:
ruby-1.8.7-p334 :036 > SomeModel.some_missing_method
call /Users/.../.rvm/gems/ruby-1.8.7-p334/gems/activerecord-2.3.12/lib/active_record/base.rb:1873 method_missing ActiveRecord::Base
line /Users/.../.rvm/gems/ruby-1.8.7-p334/gems/activerecord-2.3.12/lib/active_record/base.rb:1874 method_missing ActiveRecord::Base
line /Users/.../.rvm/gems/ruby-1.8.7-p334/gems/activerecord-2.3.12/lib/active_record/base.rb:1874 method_missing ActiveRecord::Base
line /Users/.../.rvm/gems/ruby-1.8.7-p334/gems/activerecord-2.3.12/lib/active_record/base.rb:1981 method_missing ActiveRecord::Base
line /Users/.../.rvm/gems/ruby-1.8.7-p334/gems/activerecord-2.3.12/lib/active_record/base.rb:1998 method_missing ActiveRecord::Base
c-call /Users/.../.rvm/gems/ruby-1.8.7-p334/gems/activerecord-2.3.12/lib/active_record/base.rb:1998 method_missing Kernel
raise /Users/.../.rvm/gems/ruby-1.8.7-p334/gems/activerecord-2.3.12/lib/active_record/base.rb:1998 method_missing ActiveRecord::Base
c-return /Users/.../.rvm/gems/ruby-1.8.7-p334/gems/activerecord-2.3.12/lib/active_record/base.rb:1998 method_missing Kernel
return /Users/.../.rvm/gems/ruby-1.8.7-p334/gems/activerecord-2.3.12/lib/active_record/base.rb:1998 method_missing ActiveRecord::Base
这篇关于如何找出拦截“method_missing"的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!