【问题标题】:Authorizing users on Rails 4 with CanCan based one roles in a join table使用基于连接表中的一个角色的 CanCan 在 Rails 4 上授权用户
【发布时间】:2013-11-20 13:48:21
【问题描述】:

我正在使用 Rails 4.0.0、ruby 2.0.0p247 和 CanCan 1.6.10。

如何根据用户在联接表中的角色(has_many :through)向用户授权 CanCan?

我有 3 个模型:UserGroupGroupUser

用户和组通过 GroupUser 表关联为has_many。每个 GroupUser 还有一个role 字段,可以是“编辑”或“所有者”。一个组可以有多个用户,每个用户具有不同的角色。此外,一个用户可以在多个组中拥有角色。

我设置了具有 CanCan 功能的应用程序,但不是限制只有具有正确角色的用户才能访问,它是授权每个人

模型设置如下。另外,请注意 Group 有一个方法可以返回其所有者列表。

class User < ActiveRecord::Base
  has_many :group_users
  has_many :groups, through: :group_users
end

class Group < ActiveRecord::Base
  has_many :group_users
  has_many :users, through: :group_users

  def owners
    User.find(self.group_users.where(role: 'owner').map(&:user_id))
  end
end

class GroupUser < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
end

CanCan 能力。注意它在 Group 上使用owners 方法。

class Ability
  include CanCan::Ability

  def initialize(user)

    can :update, Group do |group|
      group.owners.include?(user)
    end

  end
end

观点如下。在这里,不应该看到链接的用户仍然可以看到它。

<ul class="groups">
    <% @groups.each do |group| %>
        <li>
            <p><%= group.name %></p>
            <% if can? :update, Group %>
                <%= link_to "Edit", edit_group_path(group) %>
            <% end %>
        </li>
    <% end %>
</ul>

最后,视图的控制器动作是:

def index
  @groups = current_user.groups
end

。 . . 一件有趣的事情是,即使在实际使用过程中不起作用,下面的单元测试也通过了:

test 'user can only update groups they own' do
  ability_one = Ability.new(users(:one)) # Owner
  ability_two = Ability.new(users(:two)) # Not-owner

  assert ability_one.can?(:update, groups(:one))
  assert ability_two.cannot?(:update, groups(:two))
end

【问题讨论】:

    标签: ruby-on-rails permissions ruby-on-rails-4 authorization cancan


    【解决方案1】:

    我认为你应该在这里让cancan 使用真实对象,将实际的group 对象传递给can? 方法而不是Group 类:

    在视图中:

    <% if can? :update, group %>
    

    代替:

    <% if can? :update, Group %>
    

    这样您将询问cancan current_user 是否能够:update 实际group。由于没有为通用 Group 对象的操作设置能力,因此第二个条件将始终为真。

    【讨论】:

    • 哇,这很容易。我花了很多时间查看 cancan 文档上的checking abilities wiki,但仍然错过了这一点:“重要提示:如果存在条件块或条件散列,它们将在检查类时被忽略,它会返回 true”。谢谢你的回答。
    猜你喜欢
    • 1970-01-01
    • 2015-04-21
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 1970-01-01
    相关资源
    最近更新 更多