20

文字列を処理するための特定のメソッドや、多数のコントローラーで実行されるその他のタスクを作成しようとしています。コントローラーにヘルパーを含めるのは悪い習慣だと知っているので、コントローラーで使用されるアプリケーション全体のメソッドを配置するのに最適な場所はどこでしょうか。

モデルに入れると言う人もいると思いますが、すべてのコントローラーにモデルが関連付けられているわけではないことを理解する必要があります。ありとあらゆる入力をいただければ幸いです。

4

6 に答える 6

12

私はそれらをヘルパーに入れる傾向があります。それらが自動的にビューに含まれるという事実は、私にとって問題ではありませんでした。app/cerns/や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
于 2012-08-14T11:07:46.900 に答える
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
于 2012-08-14T10:48:23.750 に答える
9

libそれらをフォルダに入れることをお勧めします。たとえば、私は次のようにしています。

lib/utils/string_utils

module StringUtils

  def foo
     ...
  end
end

class BarController < ActionController::Base
  include StringUtils
end

これは、ファットモデル、シンコントローラーと呼ばれる優れた方法論を示しています。この場合、ロジックを分離するためにモデルの代わりにミックスインを使用していますが、考え方は同じです。コントローラはできるだけシンプルにする必要があります。

于 2012-08-14T11:53:46.740 に答える
3

それはすべてあなたのニーズに依存します。ここでは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

2番目の例-フラッシュメッセージのヘルパー

# 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ディレクトリです。

于 2012-08-14T18:12:15.533 に答える
1

Rails 4以降、専用のフォルダーがありますapp/controllers/concerns。したがって、そこでモジュールを作成し、それを特定のコントローラーに含めるか、すべてのコントローラーで使用できるようにする必要がある場合はApplicationControllerに含めることができます。

于 2017-08-10T08:04:56.803 に答える
0

これらのメソッドが多数のコントローラーで使用されている場合は、で定義しますapplication_controller.rb。すべてのコントローラーはそれを継承し、そこで定義された任意のメソッドを使用できるようになります

于 2012-08-14T10:48:58.010 に答える