我想使用rails熟悉的助手,但功能略有改变。我看待它的方式,我希望能够做到这样的事情:
module AwesomeHelper
#... create alias of stylesheet_link_tag to old_stylesheet_link_tag
def stylesheet_link_tag(*args)
if @be_awesome
awesome_stylesheet_link_tag *args
else
old_stylesheet_link_tag *args
end
end
end
我看到它的方式,我有三个选择:
所以这里的问题是,我是否坚持使用其中一种次优解决方案,还是有其他方式我没有考虑过?如果我选择选项3,有没有办法在不直接寻址rails helper模块的情况下完成它?
(注意:我删除了上下文,因为它没有对问题添加任何内容。)
答案 0 :(得分:33)
有比你列出的任何选项更好的方法。只需使用super
:
module AwesomeHelper
def stylesheet_link_tag(*sources)
if @be_awesome
awesome_stylesheet_link_tag *sources
else
super
end
end
end
在AwesomeHelper中覆盖stylesheet_link_tag
将确保在调用stylesheet_link_tag
时,Ruby会在方法查找路径中遇到它,然后才能到达ActionView::Helpers::AssetTagHelper
。如果@be_awesome
为true
,您可以在那里负责并停止操作,如果没有,则在没有括号的情况下调用super
将透明地传递所有参数直到Rails实现。通过这种方式,您无需担心Rails核心团队会在您身上移动事物!
答案 1 :(得分:6)
我不使用这个宝石,所以我会以更通用的方式回答你。
假设你要记录对link_to
助手的调用(是的,人为的例子,但显示了这个想法)。查看API可让您了解位于link_to
模块中的ActionView::Helpers::UrlHelper
。因此,您可以在您的config/initializers
目录中创建一些文件,其中包含以下内容:
# like in config/initializers/link_to_log.rb
module ActionView::Helpers::UrlHelper
def link_to_with_log(*args, &block)
logger.info '**** LINK_TO CALL ***'
link_to_without_log(*args, &block) # calling the original helper
end
alias_method_chain :link_to, :log
end
此功能的核心 - alias_method_chain
(可点击)。在定义方法xxx_with_feature
之后使用它。
答案 2 :(得分:4)
尝试使用alias_method
:
module AwesomeHelper
alias_method :original_stylesheet_link_tag, :stylesheet_link_tag
def stylesheet_link_tag(*sources)
if @be_awesome
awesome_stylesheet_link_tag *sources
else
original_stylesheet_link_tag *sources
end
end
end
答案 3 :(得分:2)
我真的鼓励你考虑你的选项#2,以一种对调用者来说显而易见的方式覆盖rails方法的行为。
您的新方法应该被称为awesome_stylesheet_link_tag
,以便其他Rails开发人员可以读取您的代码并询问“链接标记有什么特别之处?”。
作为一个较小的更改,您可以执行覆盖,但传递:awesome => true
作为参数,因此他们至少知道某些事情正在发生。
更改广泛使用的方法(如stylesheet_link_tag
)的行为会在不需要的地方产生潜在的未来误解。