2012-08-14 18 views
18

Sto cercando di scrivere determinati metodi per l'elaborazione delle stringhe e altri compiti che si svolgono in numerosi dei miei controller. Conosco la sua cattiva pratica per includere gli helper nel controller, quindi mi stavo chiedendo, dov'è il posto migliore dove mettere i metodi di applicazione utilizzati nei controller?dove mettere solo i metodi di supporto per i controller?

Mi rendo conto che alcuni di voi diranno di metterli in modelli, ma bisogna rendersi conto che non tutti i miei controllori hanno un modello associato. Qualsiasi input sarebbe apprezzato.

risposta

10

Se è necessario utilizzare un metodo nell'ambito di applicazione, suggerirei di mantenere tali metodi all'interno del controller dell'applicazione e per utilizzarli all'interno di viste .. dichiararli come metodi di supporto.

Ad esempio,

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

Il problema è che se ci sono molti metodi di supporto, 'ApplicationController' può diventare poco maneggevole.Preferisco suddividere i metodi in file helper per categoria e includendo i file in 'ApplicationController', come suggerito nella risposta di Semyon Perepelitsa. –

0

Se si utilizzano tali metodi in numerosi controllori, li definirebbero in application_controller.rb. Ogni controller erediterà da esso e sarà in grado di utilizzare qualsiasi metodo definito lì

11

Tendo a metterli in aiutanti. Il fatto che siano inclusi nelle viste automaticamente non è stato un problema per me. Puoi anche inserirli in qualcosa come app/preoccupazioni/o lib/

Non mi piace il Clustering ApplicationController con metodi privati ​​ perché questo spesso diventa un casino.

Esempio:

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

Questo è quello che faccio anch'io. –

+0

Questo ha più senso per me che riempire ogni metodo di supporto nel controller dell'applicazione. – dscher

5

vorrei suggerire di metterli nella cartella lib. Così, per esempio ho:

lib/utils/string_utils 

module StringUtils 

    def foo 
    ... 
    end 
end 

class BarController < ActionController::Base 
    include StringUtils 
end 

Questo dimostra buona metodologia denominata modello Fat, regolatore sottile, in questo caso stiamo usando Mixin invece dei modelli di separare la logica ma l'idea è la stessa. Vuoi i tuoi controller il più semplice possibile.

2

Tutto dipende dalle vostre esigenze. Fornirò qui 2 esempi. Entrambi sono solo librerie personalizzate, situate nella directory lib.

Primo esempio - "trattamento stringa personalizzata"

# 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 

Secondo esempio - aiuto per i messaggi istantanei

# 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 

Nota: Non dimenticare di aggiungere lib dir ai percorsi autoload . In config/application.rb aggiungere/modificare questa riga config.autoload_paths += %W(#{config.root}/lib). Quindi per me la risposta è la directory lib.

0

A partire da Rails 4 esiste una cartella dedicata per esso app/controllers/concerns. Quindi puoi creare un modulo lì e quindi includerlo in uno o più controller specifici o in ApplicationController se ne hai bisogno disponibile in tutti i tuoi controller.

Problemi correlati