如何找出拦截“method_missing"的内容 [英] How to find out what is intercepting 'method_missing'

查看:45
本文介绍了如何找出拦截“method_missing"的内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 Ruby 1.8.6/Rails 2.3.2

Using Ruby 1.8.6 / Rails 2.3.2

我注意到在我的任何 ActiveRecord 模型类上调用的任何方法都返回 nil 而不是 NoMethodError.除了烦人之外,这破坏了动态查找器(find_by_namefind_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"的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆