重写方法仍然被调用 [英] Overriden method still gets called

查看:65
本文介绍了重写方法仍然被调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个实现数据库中两个条目之间的 belongs_to 关联的库.由于这不是行为,因此我想通过 prepend 覆盖此方法.但是撬告诉我原来的方法仍然被调用.我仔细检查过,然后使用的是ruby 2.0.

I am using a library that is implementing a belongs_to association between two entries in a database. Since this is not the behaviour I need I want to override this method via prepend. But pry tells me that the original method is still called. I double checked and I'm using ruby 2.0.

被添加的代码:

module Associations
  module ClassMethods

    [...]
    #Add the attributeName to the belongsToAttributes
    #and add a field in the list for the IDs
    def belongs_to(attr_name)
      @belongsToAttributes ||= []
      @belongstoAttributes << attr_name

      create_attr attr_name.to_s
      attribute belongs_to_string.concat(attr_name.to_s).to_sym
    end

    def belongsToAttributes
      @belongsToAttributes
    end    
  end

  def self.included(base)
    base.extend(ClassMethods)
  end
end

# prepend the extension 
Couchbase::Model.send(:prepend, Associations)

我在课堂上使用它:

注意:我还尝试直接重写此类中的方法,但仍然没有发生

Note: I also tried to directly override the method in this class but it still doesn't happen

require 'couchbase/model'

class AdServeModel < Couchbase::Model

[...]
  #I tried to add the belongs_to method like this
  #def belongs_to(attr_name)
  #   @belongsToAttributes ||= []
  #   @belongstoAttributes << attr_name

  #   create_attr attr_name.to_s
  #    attribute belongs_to_string.concat(attr_name.to_s).to_sym
  #  end

  #  def belongsToAttributes
  #    @belongsToAttributes
  #  end
end

当我检查撬动时,它表明我最终出现在

When I check with pry it shows me that I end up in this method call:

def self.belongs_to(name, options = {})
  ref = "#{name}_id"
  attribute(ref)
  assoc = name.to_s.camelize.constantize
  define_method(name) do
    assoc.find(self.send(ref))
  end
end

任何指向我正在做错事情的指针都将不胜感激.

Any pointer to what I'm doing wrong would be appreciated.

修改:好的,我解决了这样的问题:

Ok I solved the problem like this:

 self.prepended(base)
    class << base
      prepend ClassMethods
    end
  end

end
# prepend the extension 
Couchbase::Model.send(:prepend, Associations)

由于 Arie Shaw 的帖子包含解决此问题的重要指示,因此我将接受他的回答.尽管他错过了扩展和添加我要调用的方法的要点.有关我在使用方法前遇到的麻烦的详细讨论,请参阅问题.

Since Arie Shaw's post contains important pointers to solve this problem I will accept his answer. Although he missed the point about extending and prepending the method that I want to call. For a more detailed discussion about my trouble with prepending the methods please refer to this question.

推荐答案

根据您发布的撬动跟踪,您想要猴子打补丁的方法是 AdServeModel 的类方法,而不是实例方法

According to the pry trace you posted, the method you wanted to monkey patch is a class method of AdServeModel, not a instance method.

  • The problem with your Associations module approach is, you are calling Module#prepend to prepend the module to the existing class, however, you wrote a self.included hook method which will only be called when the module is included (not prepended). You should write Module#prepended hook instead.

直接覆盖方法的问题是,您实际上是在覆盖实例方法,而不是类方法.应该是这样的:

The problem with the directly overriding approach is, you were actually overriding the instance method, rather than the class method. It should be something like this:

require 'couchbase/model'

class AdServeModel < Couchbase::Model
  class << self
    # save the original method for future use, if necessary
    alias_method :orig_belongs_to, :belongs_to

    def belongs_to(attr_name)
      @belongsToAttributes ||= []
      @belongstoAttributes << attr_name

      create_attr attr_name.to_s
      attribute belongs_to_string.concat(attr_name.to_s).to_sym
    end

    def belongsToAttributes
      @belongsToAttributes
    end
  end
end

这篇关于重写方法仍然被调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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