1

私は CanCan と Devise を使用していますが、devise ユーザーはカスタム UsersController を介して管理されています。編集リンクと破棄リンクを表示できるのは、logged_in ユーザーだけです。ただし、現在、アビリティ クラスに渡される内容に応じて、logged_in ユーザーを含むすべてのユーザーの編集リンクと破棄リンクを非表示にするか、すべてのユーザーの編集リンクと破棄リンクをすべてのsigned_inユーザーに公開するため、ユーザーは任意のユーザー アカウントを編集できます。それが彼らのものでなかった場合のイベント。

ユーザー/index.html.erb

 <% @users.each do |user| %>
    <div class="col-lg-3 col-sm-4 col-6">
       <div><%= user.email %></div>

       <% if user_signed_in? %> 

         <% if can? :update, user %>
           <div class=" btn "><%= link_to "Edit", edit_user_path(user) %> </div>
         <% end %>

         <% if can? :destroy, user %>
          <div class="btn btn-danger"><%= link_to 'Remove', user, method: :delete, data: {confirmation: 'Are you sure'} %></div>
         <% end %>

      <div><%= link_to "Sign Out", destroy_user_session_path, method: :delete  %> </div>

      <% end %> <!-- closes user_signed_in? -->
   </div>
 <% end %>

能力クラス

 class Ability
   include CanCan::Ability

   def initialize(user)
     #to ensure user object is not nil when no user object is passed in
     user ||= User.new    

     can :manage, User do |user|

     #this exposes the destroy and edit links for all users including users not yet signed_in 

      #user.id == user.id

     #this hide the destroy and edit links for all users including signed_in user
      user == :user_id 
    end
  end
end

2番目のスクリーンショットの下にUserscontrollerを追加したことに注意してください

スクリーン ショット 1 は 、アビリティ クラスのuser.id == user.idがコメント解除されている場合、まだサインインしていないユーザーを含むすべてのユーザーの破棄リンクと編集リンクを公開し、サインインユーザーは自分に属していないアカウントを編集できることを示しています。スクリーンショットでは、実際の signed_in ユーザーの電子メール アドレスはa@test.comですが、signed_in ではないユーザー (b@test.com) の編集リンクと破棄リンクにアクセスできることわかります。 ここに画像の説明を入力

スクリーン ショット 2は、アビリティ クラスでuser == :user_idのコメントを外したときに得られるものです。編集リンクと破棄リンクは、signed_in ユーザーからも隠されています。 ここに画像の説明を入力

ユーザーコントローラーの短縮版

  class UsersController < ApplicationController
     before_action :set_user, only: [:show, :update, :destroy]
     before_filter :authenticate_user!, except: [:new, :create]
     load_and_authorize_resource , only: [:index, :edit, :destroy]

     respond_to :html, :json

    def index
      @users = User.all
      respond_with @users
    end

    def edit
     #@user = User.find(params[:id])
     #respond_with @user
    end

    def destroy
      @user.destroy
      redirect_to users_path, {notice: 'A user was removed'}
    end

    private

    def set_user
      @user = User.find(params[:id])
    end

    def user_params
      params.require(:user).permit(:email, :password, :password_confirmation)
    end

  end

セッションコントローラー

 class UsersSessionsController < Devise::SessionsController
    respond_to :html, :json

    def create
      super
      if signed_in?(resource) 

        #call the code to transfer guest cart to signed_in user
        load_current_cart
      end
    end
  end

以下の@gotvaの回答で修正されました。したがって、 **can :manage, User, :id => user.idでは、 logged_inユーザーであるa@test.comだけがeditリンクとdestroyリンクを参照できます。新しいスクリーンショット:

ここに画像の説明を入力

4

2 に答える 2