根据用户的CanCan功能过滤模型的关联集合

时间:2012-11-06 15:53:07

标签: ruby-on-rails-3 cancan

用户属于某个组织。用户可以查看所有组织,但只能查看其组织内的用户。当用户查看组织时,我必须向视图添加过滤器逻辑,因此@organizations.users变为@organizations.users.select{|u| can?(:read, u)}

有没有办法更透明或更优雅地管理这个?有没有办法摆脱select{|u| can?(:read, u)}或将其移到干燥的地方?

相关代码:

class Organization < ActiveRecord::Base
  has_many :users
  ...
end

class Ability
  ...
  can :read, User, :organization => @user.organization
end

organizations / show.html.erb :(当前,sucky版本)

<% if @organization.users.select{|u| can?(:read, u)}.any? %>
  <h4>Contacts</h4>
  <ul class="unstyled">
    <% for user in @organization.users.select{|u| can?(:read, u)} %>
      <li>
        <%= link_to user, user, class: "user" %>
      </li>
    <% end %>
  </ul>
<% end %>

我希望更接近这个观点:

组织/ show.html.erb:

<% if @organization.users.any? %>
  <h4>Contacts</h4>
  <ul class="unstyled">
    <% for user in @organization.users %>
      <li>
        <%= link_to user, user, class: "user" %>
      </li>
    <% end %>
  </ul>
<% end %>

更新

我正在避免accessible_by,因为我有一个使用块的能力定义。

class Ability
  ...
  can :read, User, :organization => @user.organization
  can :read, User do |user|
    user.is? :technical_contact
  end
end

我知道accessible_by可以使用块,但仅限于提供SQL片段。由于我的用户有很多角色并存储为位掩码,因此我没有SQL片段。

1 个答案:

答案 0 :(得分:0)

CanCan使用您的有效记录模型上提供的accessible_by方法内置了对此的支持。

有关详细信息,请参阅https://github.com/ryanb/cancan/wiki/Fetching-Records