设置 cancancan 用户不能破坏自己

Setup cancancan that user couldn't destroy itself

我正在设置 cancancan 来实现这个功能: 如果用户是管理员,它可以销毁除他自己以外的所有用户。 这是我的 ability.rb

 class Ability
    include CanCan::Ability

    def initialize(user)
    if user.role == 'admin'
      cannot :destroy, User, id: user.id
    end
    end
end

这是我的观点

<h1>Listing Users</h1>

<table>
  <thead>
  <tr>
    <th>E-Mail</th>
    <th>Name</th>
    <th>Role</th>
    <th colspan="3"></th>
  </tr>
  </thead>

  <tbody>
  <% @users.each do |user| %>
      <tr>
        <td><%= user.email %></td>
        <td><%= user.name %></td>
        <td><%= user.role %></td>
        <% if can? :destroy, @user %>
        <%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %>
        <% end %>
      </tr>
  <% end %>
  </tbody>
</table>

即使使用此设置,现在每个用户都不会销毁 link。我想要的是除了管理员本人之外,每个用户后面都有一个 destroy link。我应该怎么办?谢谢!

仅仅因为管理员不能销毁自己,不授予它销毁其他用户的权限。你可以试试给它销毁权限。

class Ability
  include CanCan::Ability

  def initialize(user)
    if user.role == 'admin'
      cannot :destroy, User, id: user.id
    else
      can :destroy, User
    end
  end
end

您的主要问题是您在 @user 不存在时调用 if can? :destroy, @user

<% @users.each do |user| %>
  <% if can? :destroy, user %>
<% end %>

如果原始答案不起作用,也许您最好使用 block 来评估 user 对象:

#app/models/ability.rb
class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new
    case user.role
      when "admin"
        cannot :destroy, User do |x|
          x.id == user.id
        end
      end
    end
  end
end

这将允许您使用:

<%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } if can? :destroy, user %>

...虽然我认为解决第一个问题会解决您的问题。