2

I have a Devise User model with the attribute admin of type boolean. How can I specify in my controllers that only want certain actions to be available if admin = true? Would the following authorize method work?

def authorize
redirect_to login_url, alert:"Not authorized" if current_user.admin == false
end

Here is my Users table, admin is a boolean.

create_table "users", force: true do |t|
t.string   "email",                  default: "",    null: false
t.string   "encrypted_password",     default: "",    null: false
t.string   "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer  "sign_in_count",          default: 0,     null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string   "current_sign_in_ip"
t.string   "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
t.boolean  "admin",                  default: false
t.string   "image_file_name"
t.string   "image_content_type"
t.integer  "image_file_size"
t.datetime "image_updated_at"
t.string   "name"
end

Output of current_user inside the authorize_admin method using Pry:

NameError: undefined local variable or method `current_user' for :authorize_admin:Symbol

I am using devise so shouldn't current_user work?

Here is the output of User.first in the console:

#<User id: 1, email: "email@gmail.com", encrypted_password:    

"$2a$10$RCgzx7PJho4vegbf8Z04eumTGB1RyDl5YvDeCAMz7g3...", reset_password_token: nil,   
 reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 5,   
 current_sign_in_at: "2014-10-25 23:42:17", last_sign_in_at: "2014-10-23 00:57:07", 
 current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", created_at:   
 "2014-10-10   
19:24:39", updated_at: "2014-10-25 23:42:17", admin: false, image_file_name: nil,   
image_content_type: nil, image_file_size: nil, image_updated_at: nil, name: nil>
Joe Smith
  • 244
  • 3
  • 12

2 Answers2

1

How can I specify in my controllers that only want certain actions to be available if admin = true?

You can use rails before filter to achieve it. You can define your authorize method in application controller, which will make this method available in all of your controllers.

class ApplicationController < ActionController::Base
  private
  def authorize
    redirect_to login_url, alert:"Not authorized" if current_user.try(:admin) == false
  end
end

Now inside controller you can set before filter for methods you want to authorize.

class HomeController < ApplicationController
  before_action :authorize, only: [:your_action_name]
  def your_action_name
    #some action
  end
end

If your code has a lot of customisation depending on admin and normal users then you can also use cancancan

Mandeep
  • 9,093
  • 2
  • 26
  • 36
  • Thanks. Why should it be private? – Joe Smith Oct 25 '14 at 14:03
  • I'm just getting thrown an "undefined method admin" error. I just double checked my schema, admin is indeed a boolean property of the Users table with its default set to false. I generated my User model with Devise if that effects anything? – Joe Smith Oct 25 '14 at 14:07
  • @JoeSmith checkout [`this thread`](http://stackoverflow.com/questions/4495078/protected-and-private-methods-in-rails) for using private methods. `undefined method admin` error suggests you don't have a admin field for current_user or basically users table. Can you post output of current_user from rails console or your schema? – Mandeep Oct 25 '14 at 14:19
  • I just edited my Users table into the question. And I know what that usually means but admin is there so I am confused. – Joe Smith Oct 25 '14 at 14:26
  • @JoeSmith Ah! That's strange. Can you post the output of current_user after using a debugger or pry – Mandeep Oct 25 '14 at 14:35
  • Sorry here it is: NameError: undefined local variable or method `current_user' for :authorize_admin:Symbol – Joe Smith Oct 25 '14 at 23:37
  • @JoeSmith ah okay i think i got it. When you are not logged in current_user is nil and so we are calling admin method on nil. Try updated answer – Mandeep Oct 26 '14 at 04:53
0

I use the Declarative Authorization gem to control user access to controller actions and highly recommend it. It allows you to set up categories of users and then control which group has access to which controller actions. It's powerful, flexible and pretty easy to set up.

Steven Hirlston
  • 1,869
  • 1
  • 15
  • 19