关于Ruby on Rails 3:使用cancan可以获取未定义的局部变量或方法” roles”

using cancan getting undefined local variable or method `roles'

我已经放弃尝试锁定应用程序中的每个操作。目前,我将放置在每个控制器中,但设计/注册除外:

1
load_and_authorize_resource

在用户模型中为

1
2
3
  def role?(role)
    roles.include? role.to_s
  end

在能力模型中的

1
2
3
if user.role? :superadmin
  can :manage, :all
end

但是,出现以下错误:

1
2
3
undefined local variable or method `roles'
app/models/user.rb:33:in `role?'
app/models/ability.rb:7:in `initialize'

感谢您的帮助。

更新:由于下面的Bohdan回答,我进一步查看了文档,发现建立cancan模型的方法不同。当前,我们有6种不同的角色,导致数据库中有6种不同的布尔值字段。我当时正在考虑一种定义角色的分层方法,其中一个用户可以有多个角色,而一个角色有多个用户。有两种方法来设置角色定义。第一的。第二。为了易于使用,我认为我将详尽定义每个角色,因此每个人只有一个角色。想知道这样做的缺点是什么。

更新:我注释掉了除上述超级管理员以外的所有其他角色。意识到它与多对多问题无关。那么...?


您应该在模型中或方法roles

的任何其他自定义定义中包含has_and_belongs_to_many :roles

编辑

在将has_and_belongs_to_many :roles添加到User模型以使所有功能正常工作之后,您需要

使用至少name属性

定义名为Role的新模型

更改

1
2
3
def role?(role)
  roles.include? role.to_s
end

1
2
3
def role?(role)
  roles.map(&:name).include? role.to_s
end

编辑

迁移

1
2
3
4
5
6
7
8
9
10
11
12
class CreateRolesUsers < ActiveRecord::Migration
  def self.up
    create_table :roles_users do |t|
      t.integer :user_id
      t.integer :role_id
    end
  end

  def self.down
    drop_table :roles_users
  end
end

只需添加此迁移并运行rake db:migrate rails即可完成其余工作


用HBTM关系按字母顺序对表名进行排序。尝试将您的迁移更改为

1
create_table :user_roles