2012-11-26 44 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

啊好吧,這是有道理的。然後只是與上面相同的代碼,但與您的原始克隆應該做的伎倆。 –