我正在制作一个用于学习目的的系统。
该系统控制用户的医院轮班。用户应该只看到他的班次。
我正在使用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中直接使用空方法。
是否可以在用户控制器的索引操作中过滤列表?
答案 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 %>