Consider this code
module Auth
def sign_in(user)
#some stuff
session[:user_id] = user.id
end
end
Now, I want to include this in my application controller.
ApplicationController < ActionController::Base
include Auth
end
This makes the sign_in method available in all my controllers. Now, to make it clear that this is not a controller action, I would like to maintain the name, so my controllers read
def sign_user_in
# Some stuff
Auth.sign_in(@user)
end
This obviously does not work, because Rails will look for the class method in the Auth module. So the question is... Is it possible to include a module into the controller, preserve it's name or namespace, but still get access to the same scope as the controller? (in this case, the session variable).
So far the least bad way I have come up with is stop including the module and in the ApplicationController and instead pass the application controller instance along when calling an auth method like this:
def current_user(controller)
User.find(controller.session[:user_id])
end
Calling this method from a controller using using self as an argument works.
auth_method_name, but I really thinkAuth.method_namelooks better. JavaScript offers this thanks to it's execution context, but how does Ruby do it? If I thought there was anything beneficial about "single namespacing", I'd be programming PHP.sessionfrom inside the mixin--but only in the mixin, not in the controller. The dangers of exposure, w/o the benefits. If you're going to separate concerns, separate them, and use a service object. Simply moving functionality to a mixin doesn't make the controller any less fat: moving it to an isolated class does.sign_inin this single namespace, is not helpful either. Is it a (view) helper? Perhaps another controller action? Maybe it's inherited from ActionController::Base? Is there really nothing better than a method prefix for this?