考虑这段代码
module Auth
def sign_in(user)
#some stuff
session[:user_id] = user.id
end
end
现在,我希望将其包含在我的应用程序控制器中。
ApplicationController < ActionController::Base
include Auth
end
这使得我的所有控制器都可以使用sign_in
方法。现在,为了清楚这不是一个控制器动作,我想保留名称,所以我的控制器读了
def sign_user_in
# Some stuff
Auth.sign_in(@user)
end
这显然不起作用,因为Rails将在Auth模块中查找类方法。所以问题是......是否可以将一个模块包含到控制器中,保留它的名称或命名空间,但仍然可以访问与控制器相同的范围? (在这种情况下,会话变量)。
到目前为止,我提出的最不好的方法是停止包含模块和ApplicationController,而是在调用这样的auth方法时传递应用程序控制器实例:
def current_user(controller)
User.find(controller.session[:user_id])
end
使用self
作为参数从控制器调用此方法有效。
答案 0 :(得分:1)
试试这个吗?
对所有功能使用实际类,控制器具有该类的实例;基本上与上面完全相同的代码 - 请参阅current_user
,但您只需要一次传递控制器实例,而不是每次调用方法
module Auth
# this method is 'mixed' into controller (self)
def initialize_authorizer
@authorizer = ::Auth::Authorizer(self)
end
# this class doesn't need to be in this namespace (module), put it where ever makes sense
class Authorizer
def initialize(controller)
@controller = controller
end
attr_reader :controller
def sign_in(user)
#some stuff
controller.session[:user_id] = user.id
end
def current_user
User.find(controller.session[:user_id])
end
end
end
ApplicationController < ActionController::Base
include Auth
before_filter :initialize_authorizer
end
def sign_user_in
# Some stuff
@authorizer.sign_in(@user)
end