2012-08-14 113 views
18

我正在尋找編寫處理字符串的某些方法以及在我的許多控制器中發生的其他任務。我知道在控制器中包含助手的不好的做法,所以我只是想知道,在控制器中使用應用程序範圍方法的最佳位置在哪裏?哪裏可以放置控制器的輔助方法?

我知道你們當中有些人會說,把他們在模型中,但你必須認識到,並不是所有的我的控制器有一個相關的模型。任何和所有的輸入將不勝感激。

回答

10

如果您需要在應用範圍使用方法,那麼我會建議你保持應用程序控制器內,並以他們利用內部意見..宣佈這些作爲輔助方法,這些方法。

例如,

class ApplicationController < ActionController::Base 
helper_method :current_user, :some_method 

def current_user 
    @user ||= User.find_by_id(session[:user_id]) 
end 

def some_method 
end 
end 
+0

的問題是,如果有很多輔助方法,'ApplicationController'可以變得難以處理。正如Semyon Perepelitsa的回答所建議的,我更願意按照類別將這些方法分解爲幫助程序文件,並將這些文件包含在「ApplicationController」中。 – 2013-09-09 12:34:46

0

在情況下在許多控制器用於這些方法中,我將在application_controller.rb定義它們。每個控制器從它繼承,並能夠使用任何方法定義有

11

我傾向於把它們放進助手。它們包含在視圖 中的事實自動對我來說不成問題。你也可以將它們放到 之類的應用程序/關注/或lib/

我不喜歡使用私有方法 混亂ApplicationController,因爲這往往變得一團糟。

例子:

module AuthenticationHelper 
    def current_user 
    @current_user # ||= ... 
    end 

    def authenticate! 
    redirect_to new_session_url unless current_user.signed_in? 
    end 
end 

module MobileSubdomain 
    def self.included(controller) 
    controller.before_filter :set_mobile_format 
    end 

    def set_mobile_format 
    request.format = :mobile if request.subdomain == "m" 
    end 
end 

class ApplicationController 
    include AuthenticationHelper 
    include MobileSubdomain 
end 
+0

我也是這麼做的。 – 2013-09-09 12:32:58

+0

這對我來說比將每個幫助程序方法填入應用程序控制器更有意義。 – dscher 2014-06-18 19:12:29

5

我建議把他們在lib文件夾中。因此,例如,我有:

lib/utils/string_utils 

module StringUtils 

    def foo 
    ... 
    end 
end 

class BarController < ActionController::Base 
    include StringUtils 
end 

這說明好方法稱爲脂肪模型,薄控制器,在這種情況下,我們使用的混入,而不是模型分離邏輯,但思路是一樣的。你希望你的控制器儘可能簡單。

2

這一切都取決於您的需求。我將在這裏提供2個例子。它們都只是一個自定義庫,位於lib目錄下。

第一個例子 - 「自定義字符串處理」

# lib/filters.rb 
module Filters 

    # Converts value to canonical view 
    def self.phone(value) 
    # remove all non-digits 
    clean_value = value.gsub(/\D/, '') 

    country_codes = configus.phone.country_codes 
    area_code = configus.phone.defaults.area_code 

    case clean_value.length 
     when 7 
     "#{area_code}#{clean_value}" 
     when 11 
     # remove country code only if phone starts with the allowed country code 
     if country_codes.include?(clean_value[0].to_i) 
      clean_value[1..-1] 
     else 
      clean_value 
     end 
     else clean_value 
    end 
    end 

# usage 
# app/api/phones_controller.rb 
class Api::PhonesController < Api::ApplicationController 

    def exists 
    if params[:q] 
     clean_value = Filters.phone(params[:q]) 
     ... 
    end 
    end 
end 

第二個例子 - 幫手閃光燈消息

# lib/flash_helper.rb 
module FlashHelper 
    def flash_translate(key, options = {}) 
    scope = [:flash, :controllers] 
    scope += params[:controller].split('/') 
    scope << params[:action] 

    t(key, {:scope => scope}.merge(options)) 
    end 
end 

# app/application_controller.rb 
class ApplicationController < ActionController::Base 
    include FlashHelper 
end 

# usage 
# app/your_controller.rb 
class YourController < ApplicationController 

    def create 
    @object = Object.new(params[:object]) 

    if @object.save 
     flash[:success] = flash_translate(:success) 
     ... 
    end 
    end 
end 

注意:不要忘了lib目錄添加到自動加載路徑。在config/application.rb增加/修改這一行config.autoload_paths += %W(#{config.root}/lib)。 所以對我來說,答案是lib目錄。

0

從Rails的4起有它app/controllers/concerns一個專門的文件夾。所以你可以在那裏創建一個模塊,然後將它包含在特定的控制器或ApplicationController中,如果你需要它可以在你的所有控制器中使用。

相關問題