我使用的是Rails 4.0.0,ruby 2.0.0p247和CanCan 1.6.10。使用CanCan基於連接表中的一個角色爲Rails 4授權用戶
我如何根據CanCan在連接表(has_many:through)中的角色授權用戶?
我有3個機型:User
,Group
和GroupUser
。
用戶和組通過GroupUser表關聯爲has_many
。每個GroupUser還有一個role
字段,可以是「編輯」或「所有者」。一個組可以有多個用戶,每個用戶都有不同的角色。另外,用戶可以在多個組中具有角色。
我有應用程序的設置與慘慘的能力,但不是限制只能訪問用戶提供了正確的角色,它授權大家。
型號設置如下。另外,請注意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
哇,那很容易。我花了很多時間在cancan文檔上查看[檢查功能wiki](https://github.com/ryanb/cancan/wiki/Checking-Abilities),但仍錯過了這一點:「重要提示:如果塊或散列的條件存在時,它們將在檢查課程時被忽略,並且將返回true「。感謝您的回答。 – ahuth