带CanCanCan的Rails 5 - 如何筛选索引操作的列表

时间:2017-12-26 22:58:24

标签: ruby-on-rails ruby cancancan

我正在制作一个用于学习目的的系统。

该系统控制用户的医院轮班。用户应该只看到他的班次。

我正在使用CanCanCan进行授权控制。

因此对于索引页面我有控制器操作:

class UsersController < ApplicationController
    def index
        @users = User.all
    end
end

在index.html.erb

<% @shifts.each do |shift| %>
    <% if can? :read, shift %>
      <tr>
          <td><%= shift.date %></td>
      </tr>
    <% end %>
<% end %>

我有能力:

class Ability
    include CanCan::Ability

    def initialize(user)
        if user
            can :manage, Shift, user_id: user.id
        end
    end
end

如果他没有任何轮班,我想向用户显示一条消息。

但是在索引html页面中使用can方法,因为如果列表不为空但没有移位,则当前用户可以看到我不能在@shift中直接使用空方法。

是否可以在用户控制器的索引操作中过滤列表?

1 个答案:

答案 0 :(得分:0)

你在这里问了几个不同的问题,并且很难单独回答,所以我会采取更广泛的方法,希望能回答一些我认为你所拥有的基本问题。

第一件事是第一件事:Cancancan不会做任何与查询数据库有关的事情。 Cancancan留给你的。

我没有看到定义@shifts的位置,所以我假设它在你的ShiftsController中 - 而索引动作应该显示给定用户的移位。

给定用户通常是Rails应用程序中的current_user - 此身份验证由诸如Devise之类的东西完成。如果您的关联设置正确,则可以执行@shifts = current_user.shifts

但是,如果您希望按用户过滤班次 - 例如拥有/users/:id/shifts的RESTful路线 - 您将拥有如下所示的路线:

resources :users do 
  member do
    get :shifts => 'users#shifts'
  end
end

将使用方法UsersController映射到您的shifts

在该方法中,您将拥有一个:id参数,其中包含您对show动作所期望的值。

@shifts = Shift.where(:user_id => params[:id])

现在,如果你想过滤ShiftsController#index方法的转换,你可以这样:

@shifts = Shift.where(:user_id => params[:user_id])

,您的网址可能是/shifts?user_id=1

现在,如果用户没有任何班次,@shifts将返回一个空数组 - 表示没有与您的数据库查询匹配的行。因此,您可以在视图中执行一些简单的逻辑,

<% if @shifts.empty? %> No shifts. <% else %> ... things to list shifts <% end %>