I want to user current_user method for two purpose.
I have user gmail log in and personal registration from site.
But current_user method of devise gem is not working for gmail user.
for gmail user I used below method
helper_method :current_user
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
kindly help me to fix this.
Thanks
I got solution by my self letter on.
Below code is the solution of above problem
alias_method :devise_current_user, :current_user
def current_user
if session[:user_id].blank?
devise_current_user
else
User.find(session[:user_id])
end
end
This works fine for me
Related
I'm working on a login/logout system. Instead of using devise, I created an active records User model and use sessions to remember if a user is logged in. Everything was working fine until I added these lines in the application_controller.rb to have a layout before login and one after.
layout :set_layout
def set_layout
if session[:current_user_id]
'afterlogin'
else
'application'
end
end
Now, after I log in and cancancan is being used somewhere in a html page I get undefined local variable or method 'current_user'. I think that I have to add a current_user method but I'm not exactly where and how to define it.
Edit: I already had something similar in another class that is being used by login:
class Admin::ApplicationController < ApplicationController
before_action :authorize
def authorize
begin
#current_user ||= User.find(session[:current_user_id]) if session[:current_user_id]
rescue ActiveRecord::RecordNotFound
session.destroy
redirect_to '/login',alert: 'Please login'
end
end
end
Should I modify this after I add that method ?
CanCanCan expects a current_user method to exist in the controller.
First, set up some authentication (such as Authlogic or Devise).
See Changing Defaults if you need different behavior.
I would suggest you to install Devise so that it comes with a complimentary current_user method.
FYI: https://github.com/plataformatec/devise
UPDATE
when a user logins successfully, you can store the user's id in session.
session[:current_user_id]=user.id
so that, in your applicationcontroller, you can do
def current_user
#current_user ||= session[:current_user_id] && User.find_by_id(session[:current_user_id])
end
helper_method :current_user
I am trying to implement a survey using the surveyor gem in rails. I want to make use of the user id to keep track of which user creates the survey and which user gave what response on which survey.
The problem is that I did not use the Devise gem for my user signin and signup. I built it manually. The surveyor gem uses a helper method current_user of Devise which returns details about the current user.
Since, I did not use devise, I am not sure where to add the helper method current_user.
I am not really sure as to what code to post, so please comment the required details. I will edit my post as needed.
Thanks!
application_controller.rb
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_filter :authorize
helper_method :current_user
protected
def authorize
return true if ((self.class == SessionsController)|| (self.class == UsersController && (self.action_name == "new" || self.action_name == "create")))
unless (User.find_by_id(session[:user_id]))
redirect_to url_for(:controller => :sessions , :action => :new), alert: "You need to be logged in."
end
end
def current_user
#current_user = User.find(session[:user_id])
end
end
Here is the link of the surveyor gem controller which uses the current_user method: https://github.com/kjayma/surveyor_gui/blob/master/app/controllers/surveyor_gui/survey_controller.rb
Here is one possible solution to implement a current_user method.
helper_method would make the current_user method available in every controller, which inherits from ApplicationController.
class ApplicationController
helper_method :current_user
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
end
How do I guarantee that users only access the routes on my web app if they are logged in? I already have Users and Session models and users are able to create accounts. But how do I make sure that if they are not logged in they are always redirected to the login/sign up page, but if they are they have access to all the routes?
EDIT: So this is what my Application Controller looks like right now:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
helper_method :current_user
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
end
So if there isn't a current user, I want to allow access only to the my Pages controller and its actions (which are basically home, signup, login, etc.). If there is a user, on the other hand, I want that user to be able to access all the routes in my route file.
class SomeController < ApplicationController
def show
if current_user.nil?
redirect_to '/path/to/login'
end
end
end
could probably give a more detailed answer if you paste in some code otherwise we all are just guess what your methods are called.
If you are using devise it comes with the built in helper method authenticate_user! which should be placed in your application controller.
If you are not using devise you can define you own method (for this example I will copy devise) authenticate_user! in application controller and call the before action
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
hide_action :current_user
private
def authenticate_user!
redirect_to :root if current_user.nil?
end
end
In Michael Hartls rails tutorial , I came across the following code :
module SessionsHelper
def current_user=(user)
#current_user = user
end
def current_user #get logged in user
#current_user||=User.find_by_remember_token(:remember_token)
end
def sign_in(user) #sign the user in by setting cookies
cookies.permanent[:remember_token]= user.remember_token
current_user = user
end
def signed_in?(user) #check whether user signed in
!current_user.nil?
end
end
My SessionsController create action looks like this :
def create
user = User.find_by_email(params[:session][:email])
if user && user.authenticate(params[:session][:password])
sign_in user # sign the user in by setting cookies
else
flash.now[:error]= "Invalid email/password"
render 'new'
end
end
Why do we need a writer method def current_user=(user) in the SessionsHelper module ?
Can't we just assign the value of user to the #current_user variable directly in the sign_in method ?
Can it be done like this:
module SessionsHelper
# Notice that there is no def current_user=(user) method.
def current_user
#current_user||=User.find_by_remember_token(:remember_token)
end
def sign_in(user)
cookies.permanent[:remember_token]= user.remember_token
#current_user = user #set the current user directly withoout a writer method
end
def signed_in?(user)
!current_user.nil?
end
end
Sure you can do like that. But idea is to incapsulate instance variable and never assign it directly outside getter and setter methods and that's how ruby works. You actually cannot do SomeObject.#instanceVar=. you need setter for that.
So if in future you will need to set current_user eather you have to use sign_in method or create new method which will be like exactly setter. So why not to use it?
Why is the middle method necessary? It seems to me like it's just an intermediary step to connect the first and third methods.
module SessionsHelper
def sign_in(user)
cookies.permanent[:remember_token] = user.remember_token
self.current_user = user
end
def current_user=(user)
#current_user = user
end
def current_user
#current_user ||= User.find_by_remember_token(cookies[:remember_token])
end
end
It is the setter method or the helper method to set the current_user with the user who is currently online. This is used by devise gem to identify the current user.
So whenever you need to find the online user for your application, you just use the following code-
if current_user
#Do something important
else
#You do not have enough privileges. Please login.
#Your offline stuff
end