2008-10-10 27 views
1

我一直在重構我的模型和控制器,努力消除代碼重複,到目前爲止,它似乎都是桃色奶油狀。目前,我有一些代碼是共同的我的兩個控制器,就像這樣:如何根據控制器名稱查詢模型

def process_filters 
# Filter hash we're going to pass to the model 
    filter_to_use = {} 

    # To process filters, we first query the model to find out what filters 
    # we should be looking for, as the model knows what we can filter. 
    Iso.available_filters.each do |filter| 
    # We should have our array with our filter listing. 
    # Check the purchase order model for a description 
    filter_name = filter[0][:filter_name] 

    # Filters are stored in a session variable, this way filters survive 
    # page reloads, etc. First thing we do, is set the session if new filters 
    # have been set for the filter. 
    session_name = session_filter_name(filter_name) 
    if params[session_name] 
     if params[session_name] == 'All' 
     session[session_name] = nil 
     else 
     session[session_name] = params[session_name] 
     filter_to_use[filter_name] = params[session_name] 
     end 
    elsif session[session_name] 
     # If params aren't read, we still need to filter based off the users 
     # session 
     filter_to_use[filter_name] = session[session_name] 
    end 
    end 

    # Just using this variable for now until I can refactor the helper code 
    # so that this is passed in. 
    @current_filter_values = filter_to_use 

    filter_to_use[:page] = @current_page 

    @isos = Iso.find_filtered(filter_to_use) 

    if @isos.out_of_bounds? 
    filter_to_use[:page] = session[:previous_page] = @current_page = 1 
    @isos = Iso.find_filtered(filter_to_use) 
    end 
end 

下面這段代碼是完全一樣的另一控制器代碼,除了參考模型(在這種情況下, ISO)。有什麼我可以讓模型參考動態?

基本上我想將Iso引用(包括@iso變量)替換爲基於controller.controller_name或類似名稱的內容。

回答

2

您可以將此代碼移入模塊,在您需要的所有控制器中混入此模塊,並使用模塊內部的self.class變量來計算出具體的控制器名稱。使用這個名字,你可以使用標準的字符串函數(例如大寫)和Kernel.const_get函數來獲取類名。

+0

唉唉,我覺得Kernel.const_get是我需要知道些什麼。謝謝! – Mike 2008-10-10 04:28:29

2

好吧,這就是我最終的結果。絕不是我一個Ruby/Rails的大師,但它爲我工作,所以希望它可能會,如果他們試圖類似的東西有人指出了正確的方向:

module Filtered 
    module Controller 
    module InstanceMethods 
     def process_filters 
     # Filter hash we're going to pass to the model 
     filter_to_use = {} 

     # To process filters, we first query the model to find out what filters 
     # we should be looking for, as the model knows what we can filter. 
     Kernel.const_get( 
      self.controller_name.singularize.camelize).available_filters.each do |filter| 
      # We should have our array with our filter listing. 
      # Check the purchase order model for a description 
      filter_name = filter[0][:filter_name] 

      # Filters are stored in a session variable, this way filters survive 
      # page reloads, etc. First thing we do, is set the session if new filters 
      # have been set for the filter. 
      session_name = session_filter_name(filter_name) 
      if params[session_name] 
      if params[session_name] == 'All' 
       session[session_name] = nil 
      else 
       session[session_name] = params[session_name] 
       filter_to_use[filter_name] = params[session_name] 
      end 
      elsif session[session_name] 
      # If params aren't read, we still need to filter based off the users 
      # session 
      filter_to_use[filter_name] = session[session_name] 
      end 
     end 

     # Just using this variable for now until I can refactor the helper code 
     # so that this is passed in. 
     self.instance_variable_set('@current_filter_values', filter_to_use) 

     filter_to_use[:page] = self.instance_variable_get('@current_page') 

     self.instance_variable_set("@#{self.controller_name}", 
      Kernel.const_get(self.controller_name.singularize.camelize).find_filtered(
      filter_to_use)) 

     if self.instance_variable_get("@#{self.controller_name}").out_of_bounds? 
      filter_to_use[:page] = session[:previous_page] = 1 
      self.instance_variable_set("@#{self.controller_name}", 
      Kernel.const_get(self.controller_name.singularize.camelize).find_filtered(
       filter_to_use)) 
     end 
     end 

     private 

     # Quick helper function for generating session variable names 
     def session_filter_name(name) 
     "#{self.controller_name}_#{name}_filter".to_sym 
     end 

    end 
    end 
end 

我包括它在我所有的通過插件,init.rb文件控制器像這樣:

# Include hook for controllers 
ActionController::Base.class_eval do 
    include Filtered::Controller::InstanceMethods 
end 
相關問題