问题 如何将CanCan与多种设计模型集成?


我将如何定义几个设计模型的能力?


10469
2018-06-18 18:25


起源



答案:


让我们假设您的应用程序有两个独立的Devise驱动的用户模型 User 和 Admin。这意味着你使用像 current_user 和 current_admin 并排。

让我们进一步假设您只有/想要一个 Ability class,包含所有CanCan权限设置......

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new
    case user
    when User
      can :create, Comment
      can :read, :all
    when Admin
      can :manage, :all
    end
  end
end

这正是其他人提出的建议,但还有另一个步骤。

默认情况下,CanCan假定该方法 current_user 存在并将返回一个User对象以与您的对象进行比较 Ability 设置。但是,我们的管理员用户可以使用 current_admin。在不告诉CanCan在哪里找到管理对象的情况下,他们永远不会得到审核,因此永远不会获得权限; 我们必须在处理管理员时更改默认值。

添加以下内容 application_controller.rb...

def current_ability
  if admin_signed_in?
    @current_ability ||= Ability.new(current_admin)
  else
    @current_ability ||= Ability.new(current_user)
  end
end

现在,我们的Ability类将查看Admin对象(如果有),并且当没有可用时返回普通用户。

进一步的开发允许我们将Admin权限移动到他们自己独立的Ability类中......

def current_ability
  if admin_signed_in?
    @current_ability ||= AdminPowers.new(current_admin)
  else
    @current_ability ||= Ability.new(current_user)
  end
end

有关详细信息,请参阅 更改默认值 在维基。感谢 斯特凡 指着我正确的文章。

仅供参考 - CanCan死了,万岁 CanCanCan 最新的错误修复和新功能。相同的命名空间,所以它只是Gemfile中的一个替代宝石替代品。

gem 'cancancan', '~> 1.8'

12
2018-05-21 00:49



搜索后我终于找到了完整的答案 - coderVishal


答案:


让我们假设您的应用程序有两个独立的Devise驱动的用户模型 User 和 Admin。这意味着你使用像 current_user 和 current_admin 并排。

让我们进一步假设您只有/想要一个 Ability class,包含所有CanCan权限设置......

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new
    case user
    when User
      can :create, Comment
      can :read, :all
    when Admin
      can :manage, :all
    end
  end
end

这正是其他人提出的建议,但还有另一个步骤。

默认情况下,CanCan假定该方法 current_user 存在并将返回一个User对象以与您的对象进行比较 Ability 设置。但是,我们的管理员用户可以使用 current_admin。在不告诉CanCan在哪里找到管理对象的情况下,他们永远不会得到审核,因此永远不会获得权限; 我们必须在处理管理员时更改默认值。

添加以下内容 application_controller.rb...

def current_ability
  if admin_signed_in?
    @current_ability ||= Ability.new(current_admin)
  else
    @current_ability ||= Ability.new(current_user)
  end
end

现在,我们的Ability类将查看Admin对象(如果有),并且当没有可用时返回普通用户。

进一步的开发允许我们将Admin权限移动到他们自己独立的Ability类中......

def current_ability
  if admin_signed_in?
    @current_ability ||= AdminPowers.new(current_admin)
  else
    @current_ability ||= Ability.new(current_user)
  end
end

有关详细信息,请参阅 更改默认值 在维基。感谢 斯特凡 指着我正确的文章。

仅供参考 - CanCan死了,万岁 CanCanCan 最新的错误修复和新功能。相同的命名空间,所以它只是Gemfile中的一个替代宝石替代品。

gem 'cancancan', '~> 1.8'

12
2018-05-21 00:49



搜索后我终于找到了完整的答案 - coderVishal


当前用户模型传递给 Ability#initialize,所以你可以检查它的类:

class Ability
  include CanCan::Ability

  def initialize(model)
    case model
    when Admin
      can :manage, :all
    when User
      can :create, Comment
      can :read, :all
    else
      can :read, :all
    end
  end
end

2
2018-06-18 23:17



谢谢Stefan。不幸的是,它似乎没有起作用。它仅适用于用户案例,但不适用于管理员。每当我以管理员身份登录时,我都只拥有访客权限。可能我做错了但我无法弄明白。 - user1464499
也许 Ability#initialize 没有为您的管理员调用。添加一些日志记录并签出 更改默认值。 - Stefan


这对我有用 -

class Ability
  include CanCan::Ability

  def initialize(user)
    if user.is_a?(Admin)
      can :manage, :all
    elsif user.is_a?(User)
      can :create, Comment
      can :read, :all
    else
      can :read, :all
    end
  end
end

2
2017-09-27 02:27