简体   繁体   English

带有CanCanCan的Rails 5-如何为索引操作过滤列表

[英]Rails 5 with CanCanCan - How to filter list for an index action

I'm making a system for study purposes. 我正在建立一个用于学习目的的系统。

This system controls the hospital shifts for the user. 该系统为用户控制医院的班次。 An user should only see his shifts. 用户应该只看到他的班次。

I'm using CanCanCan for the authorization control. 我正在使用CanCanCan进行授权控制。

So for the index page the controller action I have: 因此,对于索引页,控制器具有以下操作:

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

In the index.html.erb 在index.html.erb中

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

In the ability I have: 我具有以下能力:

class Ability
    include CanCan::Ability

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

I want to show a message to the user if he doesn't have any shifts. 如果他没有任何班次,我想向用户显示一条消息。

But using the can method in index html page because if the list is not empty but there is no shift the current user can see I can't use an empty method direct in the @shift. 但是在索引html页面中使用can方法,因为如果列表不为空但没有平移,当前用户可以看到我不能直接在@shift中使用空方法。

Is it possible to filter the list in the index action in user controller? 是否可以在用户控制器的index操作中过滤列表?

You're asking a few different questions here, and it's hard to answer them individually, so I'm going to take a more broad approach in hopes of answering some of the underlying questions I believe you're having. 您在这里提出了几个不同的问题,很难逐一回答,因此我将采用更广泛的方法,希望回答我认为您所遇到的一些基本问题。

First thing's first: Cancancan does not do anything that relates to querying your database. 第一件事是:Cancancan不会做任何与查询数据库有关的事情。 Cancancan leaves that up to you. Cancancan取决于您。

I'm not seeing where @shifts is defined, so I'm going to assume it's in your ShiftsController — whereas the index action is supposed to show a given user's shifts. 我没有看到@shifts的定义位置,所以我假设它位于您的ShiftsController -而index操作应该显示给定用户的班次。

A given user is usually the current_user in Rails applications — this authentication is done by something such as Devise. 给定的用户通常是Rails应用程序中的current_user这种身份验证是通过诸如Devise之类的方式完成的。 If your associations are setup correctly, you're able to do @shifts = current_user.shifts 如果您的关联设置正确,则可以执行@shifts = current_user.shifts

But in the case that you want to, say, filter the shifts by user — such as having a RESTful route of /users/:id/shifts — you would have routes that look like this: 但是,例如,如果要按用户过滤班次,例如使用RESTful路由/users/:id/shifts ,您将拥有如下所示的路由:

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

which would map to your UsersController with a method shifts . 它将通过shifts映射到您的UsersController

Inside that method you'd have an :id param with the value that you'd expect from your show action. 在该方法内,您将具有一个:id参数,该参数具有您希望通过show动作获得的值。

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

Now, if you wanted to filter shifts on your ShiftsController#index method, you could have something like this: 现在,如果您想过滤ShiftsController#index方法上的ShiftsController#index ,则可以有以下内容:

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

and your URL would look like, presumably, /shifts?user_id=1 并且您的URL大概应该是/shifts?user_id=1

Now, if a user doesn't have any shifts, @shifts will return an empty array — indicative of no rows that match your database query. 现在,如果用户没有任何班次, @shifts将返回一个空数组-表示没有与您的数据库查询匹配的行。 Therefore, you can do some simple logic in your view, 因此,您可以在视图中执行一些简单的逻辑,

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM