I've been trying to get authentication working with devise, and then omniauth, but I haven't been able to get the user session.
In my application controller, I have
class ApplicationController < ActionController::Base
protect_from_forgery
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
end
which I got from the updated railscast https://github.com/railscasts/241-simple-omniauth/blob/master/revised/blog-after/app/controllers/application_controller.rb
In my app, I call
<% if current_user %>
but this always errors out as undefined local variable or method 'current_user'
why is this? is it a problem with my application controller, or maybe a session error with rails?
Related
I have a very frustrating issue.
I can't call any helper method from my views in rails.This is what I have:
ApplicationController.rb
class ApplicationController < ActionController::Base
protect_from_forgery
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
helper_method :all
end
/app/views/welcome/_navi_bar.haml:
%ul.nav.nav-pills.pull-right
%li.pull-right
- if current_user
%a.btn-small{"data-toggle" => "modal", :href => log_out_path, :role => "button"}
%i.icon-user.icon-white
%strong
Log Out
- else
%a.btn-small{"data-toggle" => "modal", :href => "#LoginBox", :role => "button"}
%i.icon-user.icon-white
%strong
Login
This is what I get as error:
undefined local variable or method `current_user' for #<#<Class:0x007ff0a0544668>:0x007ff0a05414b8>
I really don't get what the problem is. Please help !
You have written your code in application controller instead of application helper
That is the reason why your method is not getting called
if you want to check if current user is logged in or not
you may just use before filter in application controller and call the method
whenever you dont need to check the method add skip before filter in that place
Ryan Bates gives great screencast http://railscasts.com/episodes/360-facebook-authentication how to use "omniauth-facebook" gem. But there is some issues with:
#application_controller.rb
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
It sets #current_user too late for standart Devise auth protection for actions in controllers:
before_filter :authenticate_user!, :except => [:index, :show]
So it redirects to sign in page, even #current_user is aviable in views...
Maybe anyone knows how to fix it?
PS I saw few tricks with redirects handler, but I think there should be better decision...
I have found the simple way to sign in using standart Devise method. Based on this tutorial, just set code in sessions_controller:
#sessions_controller.rb
class SessionsController < ApplicationController
def create
user = User.from_omniauth(env["omniauth.auth"])
sign_in user
redirect_to root_url
end
end
And you can delete this from application controller:
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
I have a Rails 3.2.3 application and I am using MiniTest and Capybara to run my integration tests. I rolled my own authentication and created a current_user helper_method in my application_controller.rb.
My application layout file only displays certain links, like logout, etc., when a user is logged in.
But the current_user method does not work during tests. It looks like this:
class ApplicationController < ActionController::Base
protect_from_forgery
private
def authenticate
if current_user.blank?
redirect_to root_url, :alert => "You must first log in."
end
end
def authenticate_admin
unless current_user and current_user.admin?
redirect_to root_url, :alert => "You must be logged in as an administrator to access this feature."
end
end
def current_user
begin
#current_user ||= User.find(session[:user_id]) if session[:user_id]
rescue
nil
end
end
helper_method :current_user
end
So in my application.html.erb file there is:
<% unless current_user.blank? %>
<li><%= link_to logout_path %></li>
So this works when I test it through the browser, but not in my test. "current_user" ends up being nil.
I am new to BDD, but is there something that prevents sessions from being created during tests? What am I missing?
NOTE: helper methods defined in controllers are not included.
from here.
The solution is to organize them in a dedicated helper class.
I've a current_user method to handle authentication.
application_controller.rb
protect_from_forgery
helper_method :current_user
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
but when I try to acces a to a page I get the following error:
Couldn't find User with id=1
app/controllers/application_controller.rb:10:in `current_user'
How can I pass #current_user a sort of default value so if there's no user it will redirect to login page.
Thanks for helping.
It looks like your session contains old data, specifically an id (1) of a user which no longer exists. Try handling the RecordNotFound exception raised by ActiveRecord, and returning nil:
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
rescue ActiveRecord::RecordNotFound
end
To redirect, you should add a second before_filter which checks for a user and handles redirecting to the login path:
before_filter :require_user
def require_user
redirect_to login_path unless current_user
end
Remember to omit require_user for your login action by adding skip_before_filter :require_login to whichever controller manages your authentication.
I have authlogic set up and want to use declarative_authorization. In Ryan Bates's railcast #188 he uses
before_filter {|c| Authorization.current_user = c.current_user}
If I do the same I get an error:
`private method 'current_user' called for #<UsersController:0xa6025e8>`
The current_user method is in application controller and is private (as in the Authlogic setup example) and if I make it public, this works. It also works if I just say current_user (current_user method is also a helper) instead of c.current_user in the before filter block.
So would it actually be ok if I would just do before_filter {Authorization.current_user = current_user}?
Try this:
application_controller.rb
Add before_filter :set_current_user
Put this method into protected
def set_current_user
Authorization.current_user = current_user
end