Overriden方法仍然被调用

我正在使用一个库,该库在数据库中的两个条目之间实现belongs_to关联。 由于这不是我需要的行为,我想通过prepend覆盖此方法。 但是pry告诉我原来的方法仍然被调用。 我仔细检查了一下,我正在使用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) 

我在这堂课中使用它:

注意:我也尝试直接覆盖此类中的方法,但它仍然没有发生

 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 

当我用pry检查时,它告诉我,我最终在这个方法调用中:

 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 

任何指向我做错的指针都将不胜感激。

编辑:好的,我解决了这样的问题:

  self.prepended(base) class << base prepend ClassMethods end end end # prepend the extension Couchbase::Model.send(:prepend, Associations) 

由于Arie Shaw的post包含解决这个问题的重要指示,我将接受他的回答。 虽然他错过了关于扩展和预先设置我想要调用的方法的观点。 有关我在预先安排方法时遇到的麻烦的更详细讨论,请参阅此问题。

根据您发布的AdServeModel ,您想要修补的方法是AdServeModel的类方法,而不是实例方法。

  • 您的Associations模块方法的问题是,您正在调用Module#prepend以将模块添加到现有类,但是,您编写了一个self.included挂钩方法,该方法仅在包含模块时调用(不是前置)。 你应该编写Module#prepended hook。

  • 直接重写方法的问题是,实际上是覆盖了实例方法,而不是类方法。 它应该是这样的:

 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 
Interesting Posts