【问题标题】:method_missing override is not workingmethod_missing 覆盖不起作用
【发布时间】:2011-03-24 03:05:00
【问题描述】:

我编写了一个方便的 ActiveRecord 扩展来将方法委托给基础对象(基于multi-table inheritance

类 ActiveRecord::Base def self.acts_as(base) class_eval %Q{ def method_missing(method, *args, &blk) #{base}.send(method, *args, &blk) 救援 NoMethodError 极好的 结尾 } 结尾 结尾

我有一个 state 类和一个 base

# 状态类 类 MyState 'MyState' has_one :tail, :class_name => 'MyState' 结尾

当我尝试这个时,我发现它在某些情况下不起作用。更具体地说,

> MyState.first.some_method_in_base 零 > MyObject.first.tail.some_method_in_base NoMethodError:#<:associations::hasoneassociation:0xabcdefg> 的未定义方法“some_method_in_base”

谁能告诉我为什么一个有效而另一个无效?

【问题讨论】:

标签: ruby-on-rails ruby activerecord


【解决方案1】:

当您运行 MyObject.first.tail 时,实际响应的对象是一个 AssociationProxy

删除了大部分基本实例方法,并委托 # 通过@target 的未知方法 method_missing

您可以获取有关代理运行的更多详细信息:

MyObject.first.proxy_owner
MyObject.first.proxy_reflection
MyObject.first.proxy_target

如果您查看代码,您可以看到 AssociationProxy 将方法 some_method_in_base 代理到您的 MyState 类仅当 MyState 响应 some_method_in_base 你可以在下面的代码中看到。

  private
    # Forwards any missing method call to the \target.
    def method_missing(method, *args, &block)
      if load_target
        if @target.respond_to?(method)
          @target.send(method, *args, &block)
        else
          super
        end
      end
    end

因此,您在目标类中定义的method_missing永远不会被调用。

【讨论】:

  • 我之前在 AssociationProxy 中看到过 method_missing 的定义,但就是想不通它做了什么。这很有意义。谢谢!
  • 不客气!欢迎来到 StackOverflow 社区!如果答案是正确的并且对您有所帮助,您应该通过单击答案左侧的复选框轮廓将其标记为已接受的答案。如果你愿意,你也可以投票。有关stackoverflow.com/faq 的更多信息,请参阅“我如何在这里提问?”部分
  • 你去。复选框是模糊的。感谢您指出。
猜你喜欢
  • 1970-01-01
  • 2014-04-03
  • 1970-01-01
  • 2015-03-16
  • 2016-03-18
  • 2020-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多