devise_current_user and current_user questions - ruby-on-rails

In My ApplicationController class, I need to override the devise's current_user to use my own definition, but in some cases I also want the devise's current_user. I tried something like
alias_method :devise_current_user, :current_user
def current_user
But it doesn't seem to work. I get an undefined method current_user on the alias_method line. I have already asked this question elsewhere ( Override current_user in ApplicationController throws undefined method error ) but since it is not answered, I was wondering if I can do something like:
def devise_current_user
return Devise::Controllers::Helpers.current_user
end
What is the right way to do this?

You should be able to just do what you did:
def devise_current_user
current_user
end

Related

When should I user before_filter vs helper_method?

I have the following application_controller method:
def current_account
#current_account ||= Account.find_by_subdomain(request.subdomain)
end
Should I be calling it using a before_filter or a helper_method? What's the difference between the two and what should I consider in terms of the trade-offs in this case?
Thanks.
UPDATE FOR BETTER CLARITY
I'm finding that I can user the before_filter instead of the helper_method in that I'm able to call controller defined methods from my views. Perhaps it's something in how I arranged my code, so here is what I have:
controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
include SessionsHelper
before_filter :current_account
helper_method :current_user
end
helpers/sessions_helper.rb
module SessionsHelper
private
def current_account
#current_account ||= Account.find_by_subdomain(request.subdomain)
end
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
def logged_in?
if current_user
return true
else
return false
end
end
end
controllers/spaces_controller.rb
class SpacesController < ApplicationController
def home
unless logged_in?
redirect_to login_path
end
end
end
views/spaces/home.html.erb
<%= current_account.inspect %>
In theory, this shouldn't work, right?
There is no relationship between using before_filter or helper_method. You should use helper method when you have a method in your controller that you would like to reuse in your views, this current_account might be a nice example for helper_method if you need to use it in your views.
They are two very different things. A before_filter is something that you want to be called once before an action starts. A helper method on the other hand gets repeated often, typically in a view.
That method you have there is just fine to stay where it is.
I solved my problem. I'm new to Rails, and didn't know that methods defined in the helpers directory are automatically helper_methods. Now I'm wondering how this effects memory/performance. But at least I have the mystery solved. Thanks everyone for your help!

Rails 3 helper_method

I have setup a helper method within the application controller ie.
class ApplicationController < ActionController::Base
# Helpers
helper_method :current_user
# Private Methods
private
def current_user
#current_user ||= Tester.find(session[:user_id]) if session[:user_id]
end
end
If I try to access to current_user variable within a view im getting an error
#code
Welcome <%=#current_user.first_name%>
#error
undefined method `first_name' for nil:NilClass
I know the session is good. Is this the correct was to access to current_user ?
Thanks for the help
It's a method, you're trying to access an instance variable, do it like this:
Welcome <%= current_user.first_name%>

Ruby on rails global variable?

I'm trying to set the current user into a variable to display "Logged in as Joe" on every page. Not really sure where to begin...
Any quick tips? Specifically, what file should something like this go in...
My current user can be defined as (I think): User.find_by_id(session[:user_id])
TY :)
You might want to use something like Authlogic or Devise to handle this rather than rolling your own auth system, especially when you aren't very familiar with the design patterns common in Rails applications.
That said, if you want to do what you're asking in the question, you should probably define a method in your ApplicationController like so:
def current_user
#current_user ||= User.limit(1).where('id = ?', session[:user_id])
end
You inherit from your ApplicationController on all of your regular controllers, so they all have access to the current_user method. Also, you might want access to the method as a helper in your views. Rails takes care of you with that too (also in your ApplicationController):
helper_method :current_user
def current_user ...
Note: If you use the find_by_x methods they will raise an ActiveRecord::RecordNotFound error if nothing is returned. You probably don't want that, but you might want something to prevent non-users from accessing user only resources, and again, Rails has you covered:
class ApplicationController < ActionController::Base
protect_from_forgery
helper_method :current_user
before_filter :require_user
private
def current_user
#current_user ||= User.limit(1).where('id = ?', session[:user_id])
end
def require_user
unless current_user
flash[:notice] = "You must be logged in to access this page"
redirect_to new_session_url
return false
end
end
end
Cheers!
It belongs in your controllers.
All your controllers inheirit from Application Controller for exactly this reason. Create a method in your Application Controller that returns whatever you need and then you can access it in any of your other controllers.

Authlogic - current_user or #current_user?

please help me to understand something. In Authlogic example in UsersController it's always used #current_user, so for instance:
def show
#user = #current_user
end
(taken from http://github.com/binarylogic/authlogic_example/blob/master/app/controllers/users_controller.rb)
Why is that? In my controllers I use just current_user instead of #current_user.
And besides - Authlogic works perfectly for me, but I don't see magic columns being populated (like last_login_at or last_login_ip). Should I initialize them somehow specifically besides just adding into migration?
UPD
After some investigation, I found that if there're only fields last_login_at and last_login_ip from "Magic fields", then they will not be populated. If I add a full set of magic fields, it is working perfectly.
UPD2
My concern regarding current_user is only about UsersController: why does it have #current_user and not current_user?
current_user is typically a method defined in app/controllers/application_controller.rb which sets the #current_user instance variable if it is not already defined -- here is an example:
def current_user_session
return #current_user_session if defined?(#current_user_session)
#current_user_session = UserSession.find
end
def current_user
return #current_user if defined?(#current_user)
#current_user = current_user_session && current_user_session.record
end
Re the "magic columns", these should be set by Authlogic automatically. For example, if your user sessions controller logs in a user:
#user_session = UserSession.new(params[:user_session])
#user_session.save
Authlogic should write the last_login_at and last_login_ip attributes for you. More info in the Authlogic docs under Module: Authlogic::Session::MagicColumns
As for last_login_at and last_login_ip, do you have current_login_at and current_login_ip fields in your table ? last_login_at and last_login_ip are set with the values of current_login_at and current_login_ip before they are reset.
I think the code from the example isn't a really good example.
You shouldn't use #current_user to set the #user variable. Because it won't work if the ApplicationController#current_user method isn't called before show action of the UserController. Basically they are both exactly the same after current_user is called once.
the User Controller should look like this
class UserController < ApplicationController
def show
#user = current_user
end
end
As for the Magic Columns I have no Idea why they don't work for you.

Rails Authorization Plugin Error

I'm trying to get the permit method to work using the rails-authorization-plugin and authlogic, and I keep running into this error:
When I try:
class ApplicationController < ActionController::Base
...
before_filter permit 'admin'
...
I get this:
Authorization::CannotObtainUserObject in HomeController#index
Couldn't find #current_user or #user, and nothing appropriate found in hash
Now I do have my current_user method setup, and it works, because I used it just about everywhere else in my app:
class ApplicationController < ActionController::Base
...
helper_method :current_user
private
def current_user_session
return #current_user_session if defined?(#current_user_session)
#current_user_session = UserSession.find
end
def current_user
return #current_user if defined?(#current_user)
#current_user = current_user_session && current_user_session.record
end
...
I also know that I have users with the appropriate roles in my database, because this method works:
def require_admin
unless current_user.is_admin? || current_user.is_root?
flash[:warning] = 'You are not an administrator and cannot access this page.'
redirect_to root_path
end
end
I can make everything work if I just check on the user level using this:
before_filter :require_admin, :only => 'index'
... but shouldn't I be able to the same thing effectively with permit and permit??
Any help would be much appreciated. Let me know if you need to see more code and I'll be happy to post it. There really is nothing on Google that I can make heads-or-tails of regarding getting these two systems to work with each other.
Okay, I think I figured it out.
As Jared correctly pointed out, the proper usage is
permit 'admin'
(Not as part of a before_filter).
HOWEVER...
... the default :get_user_method is set to #current_user, which is what the acts_as_authenticated plugin uses. I, as noted earlier, am using AuthLogic, in where I have the method defined as current_user (without the pound sign).
So, I had tried the following:
permit 'admin', :get_user_method => current_user
Only to be greeted by a nice error message explaining that I had no such variable or method. What I was missing, however, is that the hash option takes a string, not a direct call to the method!! (stupid mistake, I know!)
So
permit 'admin', :get_user_method => 'current_user'
... seems to work for me.
I love Ruby and Rails, but sometimes its simplicity can be a curse of its own; I always get owned by the simple things. :)
You are using the plugin incorrectly. It should not be placed in a before filter.
On the global level, you simply declare:
permit 'admin'
That's it.
All of your actions will look for a current_user or #user object and redirect to the login page if not.
On a per-action level, you use it as a block:
def index
permit 'admin' do
#some_models = SomeModel.all
end
end

Resources