3

このコードを検討してください

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 に含めるのをやめ、代わりに、次のような認証メソッドを呼び出すときにアプリケーションコントローラーインスタンスを渡すことです。

def current_user(controller)
  User.find(controller.session[:user_id])
end

self引数としてusing を使用してコントローラーからこのメソッドを呼び出すと機能します。

4

2 に答える 2

2

これを試してみませんか?

すべての機能に実際のクラスを使用し、コントローラーにはそのクラスのインスタンスが利用可能です。基本的には上記とまったく同じコードです。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    
于 2013-05-12T14:47:16.463 に答える