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