我有一个模块:
module LiquidFilters
include ActionView::Helpers::AssetTagHelper
def stylesheet_tag(stylesheet_file_path)
stylesheet_link_tag stylesheet_file_path
end
end
我的规格:
describe LiquidFilters do
describe "#stylesheet_tag" do
it "should return the css file in an html (media=screen) tag" do
helper.stylesheet_tag("/path/css").should match(/<link href="\/path\/css\.css" media="screen" rel="stylesheet" type="text\/css"\s*\/>/)
end
end
end
但是我得到错误的参数数量(2对1)错误:
Failures:
1) LiquidFilters#stylesheet_tag should return the css file in an html (media=screen) tag
Failure/Error: helper.stylesheet_tag("/path/css").should match(/<link href="\/path\/css\.css" media="screen" rel="stylesheet" type="text\/css"\s*\/>/)
wrong number of arguments (2 for 1)
# ./app/filters/liquid_filters.rb:16:in `stylesheet_tag'
# ./spec/helpers/liquid_filters_spec.rb:13
我可以看到问题发生在stylesheet_link_tag stylesheet_file_path
模块的LiquidFilters
- stylesheet_link_tag
应该调用AssetTagHelper private method "stylesheet_tag",但最终会调用{{1} }} LiquidFilter
方法。
如何强制stylesheet_tag
调用stylesheet_link_tag
方法,而不是AssetTagHelper
?
注意:我想保留方法名称LiquidFilter
。
答案 0 :(得分:1)
您可以在AssetTagHelper
类中包含Helper
模块,以避免方法名称覆盖,如下所示:
require 'singleton'
module LiquidFilters
class Helper
include Singleton
include ActionView::Helpers::AssetTagHelper
end
def stylesheet_tag(stylesheet_file_path)
Helper.instance.stylesheet_link_tag stylesheet_file_path
end
end
这样,您的stylesheet_tag
方法就不会与AssetTagHelper
的私有方法混淆。
修改强>
根据您的反馈,我猜这是您最接近的反馈:
module LiquidFilters
include ActionView::Helpers::AssetTagHelper
alias :old_stylesheet_tag :stylesheet_tag
def stylesheet_tag(stylesheet_file_path, options = nil)
if options
old_stylesheet_tag(stylesheet_file_path, options)
else
stylesheet_link_tag stylesheet_file_path
end
end
end
你基本上覆盖私有方法,所以我认为除代理呼叫之外还有其他选择。
答案 1 :(得分:0)
Rails的alias_method_chain
可以提供帮助:
module LiquidFilters
include ActionView::Helpers::AssetTagHelper
def stylesheet_tag_with_liquid(stylesheet_file_path, options = nil)
# if this got called with two arguments, proxy them to original
if options
stylesheet_tag_without_liquid(stylesheet_file_path, options)
else
stylesheet_link_tag stylesheet_file_path
end
end
def self.included(receiver)
alias_method_chain :stylesheet_tag, :liquid
end
end
当您仍然屏蔽原始方法时,您现在可以代理它。
编辑:将alias_method_chain
移至self.included
回调,因此在模块实际包含在某处之前不会调用它。