Account :: PostsController中的NoMethodError #index

时间:2016-02-27 13:33:17

标签: ruby-on-rails

我是新手,我的rails版本是4.2.0,我安装了三个gem devise, cancancan, rolify。当我注册成功时,我收到了这条消息

NoMethodError in Account::PostsController#index
undefined method `role' for #<User:0x007fd84c2afba8>

  def admin?
    self.role.name == "admin"
  end

end

我猜问题是usersroles连接错过了。我尝试修改我的user.rb但不起作用。

这是我的app/models/ability.rb代码

class Ability
  include CanCan::Ability

  def initialize(user)
    if user.admin?
      can :manage, :all
    else
      can :update, Post do |post|
        post.user == user
      end

      can :destroy, Post do |post|
        post.user == user
      end

      can :create, Post
    end
  end
end

应用程序/模型/ user.rb

class User < ActiveRecord::Base
  has_many :posts

  ############################################################
  # not work
  # belongs_to :users_roles
  # has_and_belongs_to_many :roles, :join_tabe => :users_roles
  # has_one :users_role
  ############################################################

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  def admin?
    self.role.name == "admin"
  end
end

应用程序/模型/ role.rb

class Role < ActiveRecord::Base
  has_and_belongs_to_many :users, :join_table => :users_roles
  belongs_to :resource, :polymorphic => true

  validates :resource_type,
            :inclusion => { :in => Rolify.resource_types },
            :allow_nil => true

  scopify
end

当我注册时,我会添加一个角色来首先注册用户,这是我的application_controller.rb

def after_sign_in_path_for(resource)
  if resource.is_a?(User)
    if User.count == 1
      resource.add_role 'admin'
    else
      resource.add_role 'normal'
    end
    resource
  end
  root_path
end

schema.rb

ActiveRecord::Schema.define(version: 20160225105659) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "ckeditor_assets", force: :cascade do |t|
    t.string   "data_file_name",               null: false
    t.string   "data_content_type"
    t.integer  "data_file_size"
    t.integer  "assetable_id"
    t.string   "assetable_type",    limit: 30
    t.string   "type",              limit: 30
    t.integer  "width"
    t.integer  "height"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "ckeditor_assets", ["assetable_type", "assetable_id"], name: "idx_ckeditor_assetable", using: :btree
  add_index "ckeditor_assets", ["assetable_type", "type", "assetable_id"], name: "idx_ckeditor_assetable_type", using: :btree

  create_table "posts", force: :cascade do |t|
    t.string   "title"
    t.text     "content"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer  "user_id"
  end

  create_table "roles", force: :cascade do |t|
    t.string   "name"
    t.integer  "resource_id"
    t.string   "resource_type"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "roles", ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id", using: :btree
  add_index "roles", ["name"], name: "index_roles_on_name", using: :btree

  create_table "travel_events", force: :cascade do |t|
    t.string   "title"
    t.datetime "start_date"
    t.datetime "end_date"
    t.text     "note"
    t.integer  "travel_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "travels", force: :cascade do |t|
    t.string   "title"
    t.datetime "start_date"
    t.datetime "end_date"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  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.string   "name"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree

  create_table "users_roles", id: false, force: :cascade do |t|
    t.integer "user_id"
    t.integer "role_id"
  end

  add_index "users_roles", ["user_id", "role_id"], name: "index_users_roles_on_user_id_and_role_id", using: :btree

end

2 个答案:

答案 0 :(得分:1)

我想你忘了添加

has_one :users_role

在user.rb

答案 1 :(得分:0)

我找到了答案,但我不确定问题是表的关系。

我删除了user.rb admin方法

user.rb

class User < ActiveRecord::Base
  rolify
  has_many :posts

  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable



  # def admin?
  #  self.role.name == "admin"
  # end

end

修改ability.rb

ability.rb

class Ability
  include CanCan::Ability

  def initialize(user)
    # if user.admin?
    if user.has_role?(:admin) # modify this line
      can :manage, :all
    else
      can :update, Post do |post|
        post.user == user
      end

      can :destroy, Post do |post|
        post.user == user
      end

      can :create, Post

      can :read, Post
    end
  end
end