【问题标题】:Rails-4 Devise + CanCan not hiding edit and destroy linksRails-4 Devise + CanCan不能隐藏编辑和销毁链接
【发布时间】:2013-09-10 12:20:50
【问题描述】:

我正在使用 CanCan 和 Devise,但设计用户是通过自定义 UsersController 管理的。我只想让 login_in 用户看到 editdestroy 链接。但是现在取决于传递给能力类的内容,它要么隐藏所有用户(包括登录用户)的 editdestroy 链接,要么公开 edit 并销毁所有用户与任何已登录用户的链接,因此如果不是他们的,他们可以编辑任何用户帐户事件。

用户/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

请注意,我在第二张截图下方添加了用户控制器

屏幕截图 1 显示,如果 ability class 中的 user.id == user.id 未注释,则会暴露 destroy 和所有用户的编辑链接,包括用户尚未登录已登录用户可以编辑不属于他的帐户。在屏幕截图中,真实登录用户的电子邮件是 a@test.com,但您可以看到他可以访问 editdestroy 链接对于未登录的用户 b@test.com

屏幕截图 2,是我们在能力类中取消注释 user == :user_id 时得到的。即使是已登录用户,编辑和销毁链接也是隐藏的。

用户控制器的缩短版

  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 只有登录用户的 a@test.com 才能看到 edit销毁 链接。新截图:

【问题讨论】:

    标签: ruby-on-rails devise authorization ruby-on-rails-4 cancan


    【解决方案1】:

    尝试通过哈希(而不是块)来定义能力 https://github.com/ryanb/cancan/wiki/Defining-Abilities#hash-of-conditions

    can :manage, User, :id => user.id
    

    【讨论】:

    • 谢谢。这是我昨天首先尝试的,但没有成功,也没有抛出任何错误。我决定再试一次,因为您将其发布为答案,但它现在抛出错误:NoMethodError in Users#indexundefined method `user_id' for #<0x00000002f4e410>
    【解决方案2】:

    在你的能力范围内.rb:你试过了吗:

    user ||= User.new # guest user
    # you can here try some condition if you have multi user types
    can [:new, :create], :all
    

    【讨论】:

    • 感谢建议的答案,我已经尝试过了,但没有解决问题。
    猜你喜欢
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-07
    • 2014-03-14
    • 2012-08-01
    • 1970-01-01
    相关资源
    最近更新 更多