2012-11-26 41 views
4

我使用twitter bootstrap来创建应用程序。我正在使用Font Awesome将图标添加到各个地方,通常是链接。到目前为止,我一直在使用全球帮手。这里的简化版本:要扩展rails'`link_to`,我应该使用`alias_method_chain`还是mixins +继承?

# app/helpers/link_to_with_icon.rb 
def link_to_with_icon(text, path, options={}) 
    options = options.clone 
    icon = options.delete(:icon) 
    text = "<i class='#{icon}'></i> #{text}" if icon.present? 
    link_to(text, path, options) 
end 

这个工作,但我不得不记得每次我需要一个图标添加到一个新的链接时改变link_tolink_to_with_icon(应用程序是新的,所以这是在不断变化kindof)。所以我决定完全停止使用link_to,并用link_to_with_icon(因为它兼容)代替它。

但后来我意识到,因为我不再使用link_to,所以我不妨先修改link_to。当然,我可以在lib文件夹中添加一些monkeypatching,以使其了解:icon选项。

# lib/extensions/url_helper_extensions.rb 
module ActionView 
    module Helpers 
    module UrlHelper 

     # do some magic here 

    end 
    end 
end 

几年前,我做过类似的事情。在那段时间,帮手是这项工作的正确工具。在轨道3.x似乎是deprecated in favor of modules and inheritance

但是,如果我正确理解该页面中的示例,我需要通过某种Base模块提供link_to方法 - 否则您无法向其添加“预扩展”。

因此我的问题:我可以扩展link_to使用模块吗?或者我必须使用alias_method_chain

特别是,:icon选项的工作实现将不胜感激。

回答

3

我倒是简单地做:

# app/helpers/my_helper.rb 

module MyHelper 
    def link_to(text, path, options={}) 
    options = options.clone 
    icon = options.delete(:icon) 
    text = "<i class='#{icon}'></i> #{text}" if icon.present? 
    super(text, path, options) 
    end 
end 

但要小心,如果你曾经使用link_to用块。

+0

为什么不发送块呢?另外,你是否打算调用'link_to'方法? –

+0

@injekt多数民众赞成我的意思是,它也应该这样做 – apneadiving

+0

@apneadiving我假设你也将要包括模块在ActionView :: Helpers :: UrlHelper,对不对? – kikito

2

我要么在一个单独的辅助添加此,或将其添加到ApplicationHelper

def link_to(text, path, options = {}, &block) 
    icon = options.delete(:icon) 
    text = content_tag(:i, text, :class => icon) if icon 
    super 
end 

而且你不想克隆选项哈希,因为你不希望icon选项被发送到你原来的link_to方法。

+0

关于使用助手的好处。谢谢。关于克隆:仔细观察。 ':icon'选项没有被发送到'link_to'。但我不想直接修改'options',因为它可能在多个链接中使用(delete是一种破坏性方法,它修改了散列)。 – kikito

+0

啊好吧,这是有道理的。然后只是与上面相同的代码,但与您的原始克隆应该做的伎俩。 –