在下拉列表中显示可以管理的角色的CanCanCan角色

时间:2016-08-10 13:10:13

标签: ruby-on-rails ruby ruby-on-rails-4 cancancan

我有一个下拉列表,可以使用CanCanCan在我的Rails 4.2应用程序中更改用户的角色。 User :: ROLES字符串数组包含用户可以拥有的不同角色。要在下拉列表中显示角色:

<%= f.select :role, options_for_select((User::ROLES), @user.role) %>

我想根据CanCanCan将下拉选项限制为当前登录用户can :manage的角色。不应在下拉列表中填充当前用户没有:manage权限的角色。任何指导都表示赞赏。

编辑:

如果与字符串文字进行比较,Sean Huber的答案是完美的。但是,我意识到问题是我在我的用户模型中定义了这个数组,但我需要与ability.rb中更深层次设置的角色进行比较。以下是如何在ability.rb中设置用户模型权限的示例:

这是有道理的,但我意识到它不会真正起作用,因为它与User :: ROLES数组中的文字进行比较。

ability.rb中设置角色访问权限的代码如下所示。我需要检查指定的具体角色:

if user.role? :superadmin
  can :manage, User, role: 'admin'
end

如何与:superadmin标记化角色:manage访问权限而不是User::ROLES中的文字进行比较?

User.rb中ROLES的定义:

ROLES = %w[student teacher school district reseller admin superadmin god]

3 个答案:

答案 0 :(得分:0)

在控制器中执行的任何操作都应该有一些设置@user字段的代码,并且组装一个可供视图使用的角色集合。在您的情况下,决定在控制器方法中应该将哪些角色包含在传递给视图的集合中。

最简单的方法遍历您的角色,使用CanCanCan测试它们,然后将它们添加到options_for_select可以使用的过滤集合中。

def some_method

  @user = User.find(params[:id])
  @roles = Array.new

  User::ROLES each do | role |
    if can? :manage role
      @roles.push(role)
    end
  end

end

答案 1 :(得分:0)

这是一个单行解决方案:

<%= f.select :role, options_for_select(User::ROLES.map{|r| can?(:manage, r) ? r : nil}.compact, @user.role) %>

答案 2 :(得分:0)

我最终使用take来解决此问题:

<%= f.select :role, options_for_select(User::ROLES.take(User::ROLES.index(current_user.role)), @user.role) %>