Where is the best place to check whether it is admin or normal user logged in?

Based on railstutorials.org, I’ve written my method to check whether it is admin or not inside sessions_helper.rb. Now in model I’ve to insert data to temporary table lets assume “user_temp_table”, if it is normal user that has logged in. Later those entries will be approved by admin. If it is admin himself logged in I want to insert data to permanent table lets assume "admin_table".

Now where is the best place to call admin checking method which I have written inside sessions_helper.rb.

I have two possibilities.

  1. Set a flag to 1 or 0 inside controller and access that flag variable from model if it is admin or user respectively.

Problem: But I found some blogs and stackoverflow posts stating that controller is just a bridge between view and model. And variables inside controller should not be accessed from model. Addition to that I don’t know how to access controller variable from model. If this is the method please tell me how?

  1. include SessionHelper inside model and call the method.

But posts I found related to both of these solutions are very old. So in rails 4 which is the valid and good way to carry out this task? Or is there is any other new way?

Thank you.

Based on railstutorials.org, I've written my method to check whether it is
admin or not inside sessions_helper.rb. Now in model I've to insert data to
temporary table lets assume "user_temp_table", if it is normal user that has
logged in. Later those entries will be approved by admin. If it is admin
himself logged in I want to insert data to permanent table lets assume
"admin_table".

Now where is the best place to call admin checking method which I have
written inside sessions_helper.rb.
I have two possibilities.

1. Set a flag to 1 or 0 inside controller and access that flag variable from
model if it is admin or user respectively.
Problem: But I found some blogs and stackoverflow posts stating that
controller is just a bridge between view and model. And variables inside
controller should not be accessed from model. Addition to that I don't know
how to access controller variable from model. If this is the method please
tell me how?

2. include SessionHelper inside model and call the method.

But posts I found related to both of these solutions are very old. So in
rails 4 which is the valid and good way to carry out this task? Or is there
is any other new way?

Not sure what your helper method is doing, but I think I would have a
method in the user model so you can just say
if current_user.admin?
or something similar.

Colin

Can you share the content of session_help.rb? In lieu of that…

I am offering very simple suggestions, which I think are true for both Rails 3 and 4. You might want to explore the gem Devise for more spiffy user authentication.

On creation of a new user, in your database users table, do you set a flag to indicate whether or not the user is admin, let’s say the field is ‘is_admin’ and 1 indicates admin and 0 indicates not admin.

The Controller informs your Model.

When the user logs in, you have a controller method that manages login. You try to find the user by params like username, password, email or some combination…

User Controller:

def login ## or whatever you use…
@user = User.find ( params[:username] …
unless @user.blank?
session[:user_id] = @user.id ## Something I do…
current_user = @user
## current_user is a helper method, in my case it is located in my Application Controller… it is an instance of your current session user . If current_user does not ring familiar, do a search for it on
## your application. It may be in your Application controller. If you can’t find it, let me know… Perhaps, your session_helper.rb is serving this function/purpose?? Maybe the instance names are not the same.
## Now current_user has been informed of admin status

end

Now in your User model you need a def that returns admin status

Model

def is_admin?
is_admin == 1 ? true : false ## or however you would like
end

So now in views and controllers, you can make a call to current_user.is_admin?: eg, if current_user.is_admin? … content … end

Hope this helps.

Liz

-By the way, I have this funny feeling that you may be able to consolidate your user_temp_table and admin_table tables. Perhaps in utilization of yes/no flags? Would you might sharing the structure of each?
-And I deleted the above response, my kid startled me and I hit some wrong keys that caused a posting of an incomplete response…

Can you share the content of session_help.rb?

Yes no problem.

This is my session_helper.rb

module SessionsHelper
def log_in(user)
session[:user_id] = user.id
end

def current_user
@current_user ||= User.find_by(id: session[:user_id])
end

Returns true if the given user is the current user.

def current_user?(user)
user == current_user
end

def logged_in?
!current_user.nil?
end

Redirects to stored location (or to the default).

def redirect_back_or(default)
redirect_to(session[:forwarding_url] || default)
session.delete(:forwarding_url)
end

Stores the URL trying to be accessed.

def store_location
session[:forwarding_url] = request.url if request.get?
end

def log_out
session.delete(:user_id)
@current_user = nil
session.delete(:isitadmin)
end

def admin(role)
session[:isitadmin] = role
end

def checkadmin
admin?(session[:isitadmin])
end

def admin?(rolea)
rolea == 1
end
end
end

``

This is my sessions_controller.rb file

def loginnow
role = User.where(userid: params[:session][:userid]).pluck(:roleid)
user = User.find_by(userid: params[:session][:userid])
if user && user.authenticate(params[:session][:password])
# Log the user in and redirect to the user’s show page.
admin role
log_in user

  if admin?(role)
    flash.now[:info] = 'You are logged in as Admin and your roleid is #{role}'
    redirect_to dashboard_index_path
    puts "*******************************************************************************************************"
    puts "The roleid is #{rolea} executed in if part"                
    puts "*******************************************************************************************************"
  else
    flash.now[:danger] = 'For some reason you are not recognized as Admin and the roleid is #{role}'
    redirect_to dashboard_index_path
    puts "*******************************************************************************************************"
    puts "The roleid is #{role} executed in else part"                
    puts "*******************************************************************************************************"
  end

``

On creation of a new user, in your database users table, do you set a flag to indicate whether or not the user is admin, let’s say the >field is ‘is_admin’ and 1 indicates admin >and 0 indicates not admin.

Instead of flag I have roleid field which will be 1 for admin, 2 for clerk, 3 for accountant etc

And rest of the code is similar to mine. Instead of accessing controller method, I am passing role id as parameters while calling model method. It is not the problem right now.

The problem is,

In the loginnow method of sessions_controller, If admin?(rolea) always go to else part. To find this out I used “puts” and whether the id is 2 or 1, always else part is executing.

Not sure what your helper method is doing

Hello Colin

I’ve pasted my helper method in my recent post. Only methods starting from admin is added by me. Other methods like current_user or any user related methods are from railstutorials.org.

Thank you.

Why do you not use
if current_user.roleid == 1
to test if the logged in user is admin or not?

Colin

Why do you not use

if current_user.roleid == 1

to test if the logged in user is admin or not?

Same result.

When I logged in as admin, this is the result

Why do you not use

if current_user.roleid == 1

to test if the logged in user is admin or not?

Hey colin ignore my last message. I just tried by inserting 1 in between quotes like this and it worked!!

if current_user.roleid == “1”.

May be it was considering 1 as Boolean value or something.

Thank you for if condition without the need of those three admin methods.

Thank you again

Check the field type you specified for roleid in the database. I
guess you have it as a string not an integer, hence the need to check
for string "1" not number 1.

Now probably you want to introduce a method in User
def admin?
  roleid == "1"
end

then you can say if current_user.admin?

Colin

But the thing is, whether I put flash.now before or after “redirect_to”, its not displaying the flash message.

Well that is a different issue. How are you displaying the flash message?

Colin

I inserted some suggestions into your code…

module SessionsHelper
def log_in(user)
session[:user_id] = user.id
end

def current_user
@current_user ||= User.find_by(id: session[:user_id])
end

Returns true if the given user is the current user.

def current_user?(user)
user == current_user
end

def logged_in?
!current_user.nil?
end

Redirects to stored location (or to the default).

def redirect_back_or(default)
redirect_to(session[:forwarding_url] || default)
session.delete(:forwarding_url)
end

Stores the URL trying to be accessed.

def store_location
session[:forwarding_url] = request.url if request.get?
end

def log_out
session.delete(:user_id)
@current_user = nil
session.delete(:isitadmin)
end

def admin(role)
session[:isitadmin] = role
end

I don’t think you need this

``

#def checkadmin

admin?(session[:isitadmin])

end

``

You are making the call to admin? to verify whether or not a current_user has roleid type '1', eg is an admin.  I believe this should read

 def admin?    (no argument)
    current_user.roleid == "1" ? true : false    (roleid, as you indicate below,  is the field that is storing that flag.  Need to test it as a string.  
  end

def admin?(rolea)
rolea == 1
end

``

end
end

``

This is my sessions_controller.rb file

def loginnow
role = User.where(userid: params[:session][:userid]).pluck(:roleid) ## This call isn’t necessary

``

user = User.find_by(userid: params[:session][:userid]) ## you should verify validity of session[:userid], and then check validity of user
if user && user.authenticate(params[:session][:password])
# Log the user in and redirect to the user’s show page.
admin user.roleid.to_s ## to_s may not be necessary
log_in user

``

    Change this to     if user.admin?