I have a problem finding out how to check for admin rights in CanCanCan.
With
if user.admin?
I get undefined methodif user.is?
I get undefined methodif user.has_attribute?(:admin)
if user.user_type == "admin"
I get undefined methodI had some hopes with has_attribute, but it does not help, even if I get no alert. A puts 'hey'
proves it in the console.
I started learning Rails a month ago and I experienced some limitations due to windows. Is it possible that my problem occurs because of windows?
On the other hand,
if user.present?
works and it gives some hopes again.
My user model:
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :posts, dependent: :destroy
end
And the DB fields
create_table "active_admin_comments", force: :cascade do |t|
t.string "namespace"
t.text "body"
t.string "resource_type"
t.integer "resource_id"
t.string "author_type"
t.integer "author_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["author_type", "author_id"], name: "index_active_admin_comments_on_author_type_and_author_id"
t.index ["namespace"], name: "index_active_admin_comments_on_namespace"
t.index ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource_type_and_resource_id"
end
create_table "admin_users", force: :cascade 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", null: false
t.datetime "updated_at", null: false
t.index ["email"], name: "index_admin_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_admin_users_on_reset_password_token", unique: true
end
create_table "posts", force: :cascade do |t|
t.string "title"
t.text "body"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.integer "author_id"
end
create_table "users", force: :cascade 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", null: false
t.datetime "updated_at", null: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
From application_controller.rb
def access_denied(exception)
respond_to do |format|
format.json { head :forbidden, content_type: 'text/html' }
format.html { redirect_to main_app.root_url, notice: exception.message }
end
end
EDIT
I thought for a while that the code suggested by @mrzasa would bring a solution as I had no more alert. This was because of my ability.rb :
if user.present?
if user.admin?
puts 'hey admin'
can :manage, :all
end
can :read, all
can :manage, Post, :author_id => user.id
puts 'hey user'
end
If I comment
# if user.present?
the alertundefined method 'admin?'
comes back again. A proof that user.present works, but here to say that there is no user, until I log in outside of the admin panel as a user and then I can see the puts in the console. But I can't perform any action, unless I statecan :manage, :all
to ANY user.
At this stage, I've added user ||= User.new
to create an instance of user before checking for an admin. Even if I allow any visitor to log in as an admin, user.admin? is never verified, unless I set def admin?
to true in user.rb
I see that many people using Cancancan define roles instead. Maybe I should go for it...
EDIT 2
It works! I worked on it again from the install of Cancancan to the point where I was with the additions of @mrzasa. This time, active admin understands admin? from the class AdminUser which was not the case yesterday. The beautiful thing is that I did not change any line of code, except commenting
# user ||= User.new
to get the expected results.
It seems that you have two separate models - one for regular users (users
table) and another one for admin (admin_users
table). You can add admin?
method to both of them - for users returning false and for admin - true.
class User < ApplicationRecord
# ...
def admin?
false
end
end
class AdminUser < ApplicationRecord
# ...
def admin?
true
end
end