簡體   English   中英

Rails:包含模塊,但維護模塊名稱?

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM