未定义的方法`admin?'与康康

时间:2018-03-27 13:00:08

标签: ruby-on-rails ruby ruby-on-rails-5 cancan

我在查找如何在CanCanCan中检查管理员权限时遇到问题。

使用

  • if user.admin?我得到了未定义的方法
  • if user.is?我得到了未定义的方法
  • if user.has_attribute?(:admin)
  • if user.user_type == "admin"我得到了未定义的方法

我对has_attribute抱有一些希望,但即使我没有得到警报也没有用。 puts 'hey'在控制台中证明了这一点。

一个月前我开始学习Rails,由于windows,我遇到了一些限制。我的问题是否可能因为窗户而发生?

  

另一方面,if user.present?起作用,它再次带来一些希望。

我的用户模型:

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

数据库字段

  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

来自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 

修改

  

我想了一段时间@mrzasa建议的代码会带来一个解决方案,因为我没有更多的警报。这是因为我的能力.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 user.present?,则警告undefined method 'admin?'会再次出现。 user.present可以运行的证明,但是这里说没有用户,直到我以管理员身份登录管理面板之外,然后我可以在控制台中看到puts。但我无法执行任何操作,除非我向任何用户说明can :manage, :all

在此阶段,我已添加user ||= User.new以在检查管理员之前创建用户实例。即使我允许任何访问者以管理员身份登录user.admin?永远不会验证,除非我在user.rb

中将def admin?设置为true

我看到很多人使用Cancancan来定义角色。也许我应该去...

编辑2

  

有效!我从Cancancan的安装再次开始工作,直到我加入了@mrzasa。这次,主动管理员了解管理员?来自AdminUser类,昨天并非如此。美妙的是,除了评论# user ||= User.new以获得预期结果外,我没有更改任何代码行。

1 个答案:

答案 0 :(得分:2)

您似乎有两个单独的模型 - 一个用于常规用户(users表),另一个用于admin(admin_users表)。您可以向这两个方法添加admin?方法 - 对于返回false和admin - true的用户。

class User < ApplicationRecord
  # ...
  def admin?
    false
  end
end

class AdminUser < ApplicationRecord
  # ...
  def admin?
    true
  end
end