我已经看到了宝石中引用*_without_*
方法的几个地方,我看不到它们被定义的位置。以下是validationgroup
和delayed_jobs
宝石中的两个示例。
在validation_group.rb中,定义了一个方法add_with_validation_group
,在其最后一行引用add_without_validation_group
;但是,add_without_validation_group
似乎没有在任何地方定义。
def add_with_validation_group(attribute,
msg = @@default_error_messages[:invalid], *args,
&block)
add_error = true
if @base.validation_group_enabled?
current_group = @base.current_validation_group
found = ValidationGroup::Util.current_and_ancestors(@base.class).
find do |klass|
klasses = klass.validation_group_classes
klasses[klass] && klasses[klass][current_group] &&
klasses[klass][current_group].include?(attribute)
end
add_error = false unless found
end
add_without_validation_group(attribute, msg, *args,&block) if add_error
end
在DelayedJob的message_sending.rb中,动态传递的方法参数被称为#{method}_without_send_later
。但是,我只看到此gem中任何位置#{method}_with_send_later
被定义的位置。
def handle_asynchronously(method)
without_name = "#{method}_without_send_later"
define_method("#{method}_with_send_later") do |*args|
send_later(without_name, *args)
end
alias_method_chain method, :send_later
end
所以我的信念是,这些“没有”方法缺少一些Rails魔法。但是,我似乎无法弄清楚在谷歌搜索什么来自己回答这个问题。
答案 0 :(得分:4)
这是alias_method_chain
为您提供的内容。
基本上当你说
时alias_method_chain :some_method, :feature
提供了两种方法:
some_method_with_feature
some_method_without_feature
当调用原始some_method
时,实际上会调用some_method_with_feature
。然后你会得到some_method_without_feature
的引用,这是你原来的方法声明(即后备/默认行为)。所以,你要定义some_method_with_feature
来实际做东西,就像我说的那样,当你打电话给some_method
示例:
def do_something
"Do Something!!"
end
def do_something_with_upcase
do_something_without_upcase.upcase
end
alias_method_chain :do_something, :upcase
do_something # => "DO SOMETHING!!"
请参阅文档here: