重写方法仍然被调用 [英] Overriden method still gets called
问题描述
我正在使用一个实现数据库中两个条目之间的 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.
-
您的
Associations
模块方法的问题是,您正在调用Module#prepend
将prepend
模块添加到现有类中但是,您编写了一个self.included
挂钩方法,该方法仅在包含模块时才调用(不带前缀).您应该编写Module#prepended
代替.
The problem with your
Associations
module approach is, you are callingModule#prepend
toprepend
the module to the existing class, however, you wrote aself.included
hook method which will only be called when the module is included (not prepended). You should writeModule#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屋!