我正在使用一个在数据库中的两个条目之间实现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检查时,它显示我最终进入this方法调用:
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 的帖子包含解决此问题的重要指示,我将接受他的回答。虽然他错过了关于扩展和预先设置我想要调用的方法的观点。有关我在预先设置方法时遇到问题的更详细讨论,请参阅this问题。
答案 0 :(得分:1)
根据您发布的pry trace,您想要修补的方法是AdServeModel
的类方法,而不是实例方法。
Associations
模块方法的问题是,您正在向现有类调用Module#prepend
到prepend
模块,但是,您编写了self.included
hook方法,只有在包含模块时才会被调用(不是前置)。你应该写Module#prepended
钩子。
直接重写方法的问题是,实际上是覆盖了实例方法,而不是类方法。它应该是这样的:
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