Rails:使用关联时,不会在模型上调用method_missing

Tom*_*ghe 2 ruby-on-rails associations method-missing belongs-to

我目前的代码:

class Product < ActiveRecord::Base
  belongs_to :category
end

class Category < ActiveRecord::Base
  def method_missing name
    true
  end
end

Category.new.ex_undefined_method          #=> true
Product.last.category.ex_undefined_method #=> NoMethodError: undefined method `ex_undefined_method' for #<ActiveRecord::Associations::BelongsToAssociation:0xc4cd52c>
Run Code Online (Sandbox Code Playgroud)

这是因为rails中的这个代码只传递模型中存在的方法.

private
def method_missing(method, *args)
  if load_target
    if @target.respond_to?(method)
      if block_given?
        @target.send(method, *args)  { |*block_args| yield(*block_args) }
      else
        @target.send(method, *args)
      end
    else
      super
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

这就是我要的:

Product.last.category.ex_undefined_method #=> true
Run Code Online (Sandbox Code Playgroud)

我怎么能做到这一点?

Cho*_*ett 8

请注意,该AssociationProxy对象仅发送目标声明的方法respond_to?.因此,这里的修复也是更新respond_to?:

class Category < ActiveRecord::Base
  def method_missing(name, *args, &block)
    if name =~ /^handleable/
      "Handled"
    else
      super
    end
  end

  def respond_to?(name)
    if name =~ /^handleable/
      true
    else
      super
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

事实上,如果你重新定义,你应该总是更新- 你已经改变了你的类的界面,所以你需要确保每个人都知道它.看到这里.respond_to?method_missing