Подтвердить что ты не робот

Где ставить только вспомогательные методы для контроллеров?

Я хочу написать определенные методы обработки строк и другие задачи, которые выполняются во многих моих контроллерах. Я знаю, что его плохая практика заключается в включении помощников в ваш контроллер, поэтому мне просто интересно, где лучшее место для применения широкого спектра приложений, используемых в контроллерах?

Я понимаю, что некоторые из вас скажут, чтобы помещать их в модели, но вы должны понимать, что не все мои контроллеры имеют связанную модель. Будет оценен любой вход.

4b9b3361

Ответ 1

Если вам нужно использовать метод в области приложения, я бы предположил, что вы храните эти методы внутри контроллера приложения и чтобы использовать их внутри представлений.. объявите их как вспомогательные методы.

Например,

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

Ответ 2

Я стараюсь помещать их в помощников. Тот факт, что они включены в представления автоматически не было проблемой для меня. Вы также можете разместить их в что-то вроде приложения/проблем/или 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

Ответ 3

Я бы предложил разместить их в папке lib. Так, например, у меня есть:

lib/utils/string_utils

module StringUtils

  def foo
     ...
  end
end

class BarController < ActionController::Base
  include StringUtils
end

Это демонстрирует хорошую методологию под названием Fat model, Thin controller. В этом случае мы используем Mixins вместо моделей для разделения логики, но идея такая же. Вы хотите, чтобы ваши контроллеры были как можно более простыми.

Ответ 4

Все зависит от ваших потребностей. Я приведу здесь 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 dir в пути автозагрузки. В config/application.rb добавить/изменить эту строку config.autoload_paths += %W(#{config.root}/lib). Поэтому для меня ответ - lib.

Ответ 5

Если эти методы используются в многочисленных контроллерах, я бы определил их в application_controller.rb. Каждый контроллер будет наследовать от него и сможет использовать любой метод, определенный там.

Ответ 6

Начиная с Rails 4 для него есть выделенная папка app/controllers/concerns. Таким образом, вы можете создать модуль там, а затем включить его в определенный контроллер или в ApplicationController, если он вам понадобится на всех ваших контроллерах.