我正在寻找编写处理字符串的某些方法以及在我的许多控制器中发生的其他任务。我知道在控制器中包含助手的不好的做法,所以我只是想知道,在控制器中使用应用程序范围方法的最佳位置在哪里?哪里可以放置控制器的辅助方法?
我知道你们当中有些人会说,把他们在模型中,但你必须认识到,并不是所有的我的控制器有一个相关的模型。任何和所有的输入将不胜感激。
我正在寻找编写处理字符串的某些方法以及在我的许多控制器中发生的其他任务。我知道在控制器中包含助手的不好的做法,所以我只是想知道,在控制器中使用应用程序范围方法的最佳位置在哪里?哪里可以放置控制器的辅助方法?
我知道你们当中有些人会说,把他们在模型中,但你必须认识到,并不是所有的我的控制器有一个相关的模型。任何和所有的输入将不胜感激。
如果您需要在应用范围使用方法,那么我会建议你保持应用程序控制器内,并以他们利用内部意见..宣布这些作为辅助方法,这些方法。
例如,
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
在情况下在许多控制器用于这些方法中,我将在application_controller.rb
定义它们。每个控制器从它继承,并能够使用任何方法定义有
我倾向于把它们放进助手。它们包含在视图 中的事实自动对我来说不成问题。你也可以将它们放到 之类的应用程序/关注/或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
我也是这么做的。 – 2013-09-09 12:32:58
这对我来说比将每个帮助程序方法填入应用程序控制器更有意义。 – dscher 2014-06-18 19:12:29
我建议把他们在lib
文件夹中。因此,例如,我有:
lib/utils/string_utils
module StringUtils
def foo
...
end
end
class BarController < ActionController::Base
include StringUtils
end
这说明好方法称为脂肪模型,薄控制器,在这种情况下,我们使用的混入,而不是模型分离逻辑,但思路是一样的。你希望你的控制器尽可能简单。
这一切都取决于您的需求。我将在这里提供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
目录。
从Rails的4起有它app/controllers/concerns
一个专门的文件夹。所以你可以在那里创建一个模块,然后将它包含在特定的控制器或ApplicationController中,如果你需要它可以在你的所有控制器中使用。
的问题是,如果有很多辅助方法,'ApplicationController'可以变得难以处理。正如Semyon Perepelitsa的回答所建议的,我更愿意按照类别将这些方法分解为帮助程序文件,并将这些文件包含在“ApplicationController”中。 – 2013-09-09 12:34:46