[英]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.