[英]Rails: Include module, but maintain module name?
考虑这段代码
module Auth
def sign_in(user)
#some stuff
session[:user_id] = user.id
end
end
现在,我想将其包含在我的申请 controller 中。
ApplicationController < ActionController::Base
include Auth
end
这使得sign_in
方法在我的所有控制器中都可用。 现在,为了明确这不是 controller 操作,我想保留名称,所以我的控制器读取
def sign_user_in
# Some stuff
Auth.sign_in(@user)
end
这显然是行不通的,因为 Rails 会在 Auth 模块中寻找 class 方法。 所以问题是......是否可以将一个模块包含到 controller 中,保留它的名称或名称空间,但仍然可以访问与 controller 相同的 scope? (在本例中为 session 变量)。
到目前为止,我想出的最不坏的方法是停止在 ApplicationController 中包含模块,而是在调用这样的 auth 方法时传递应用程序 controller 实例:
def current_user(controller)
User.find(controller.session[:user_id])
end
使用self
作为参数从 controller 调用此方法有效。
试试这个?
使用实际的 class 来实现所有功能,controller 有一个可用的 class 实例; 基本上与上面的代码完全相同 - 请参阅current_user
但您只需要一次传递 controller 实例,而不是在每次方法调用时传递
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
我问这个问题已经 9 年了。 与此同时,我意识到这样做不是一个好主意,因为它会影响语言。
常量有自己的self
,当引用常量时,您会期望任何方法都是 class 方法。 除非在方法调用期间显式传递引用,否则您不会期望它们能够访问调用 object,在这种情况下,您具有双向依赖性,这会带来一系列问题。 那将是一种代码味道,应该成为重构软件设计的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.