微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我的CanCan Ability课程过度放任?

如何解决为什么我的CanCan Ability课程过度放任?

| 我(最后)将CanCan / Ability连接到我的应用程序中,并且我首先编写了RSpec测试。但是他们失败了-我的能力似乎过于宽容,我不明白为什么。 首先是能力类。目的是非管理员用户只能自己管理。特别是,他们不能查看其他用户
class Ability
include CanCan::Ability

  def initialize(user)
    user ||= User.new           # create guest user if needed
    if (user.has_role?(:admin))
      can(:manage,:all)
    else
      can(:manage,User,:id => user.id)
    end
  end
end
RSpec测试:
require \'spec_helper\'
require \'cancan/matchers\'

describe Ability do
  before(:each) do
    @user = User.create
  end

  describe \'guest user\' do
    before(:each) do
      @guest = nil
      @ability = Ability.new(@guest)
    end

    it \"should_not list other users\" do
      @ability.should_not be_able_to(:read,User)
    end

    it \"should_not show other user\" do
      @ability.should_not be_able_to(:read,@user)
    end

    it \"should_not create other user\" do
      @ability.should_not be_able_to(:create,User)
    end

    it \"should_not update other user\" do
      @ability.should_not be_able_to(:update,@user)
    end

    it \"should_not destroy other user\" do
      @ability.should_not be_able_to(:destroy,@user)
    end
  end
end
所有这五个测试均失败。我已经阅读了Ryan的文档部分,他说:   重要提示:如果   存在条件将被忽略   在上课时,它将   返回true。 ...但是最多只能解释五个失败中的两个。很明显,我缺少基本的东西。     

解决方法

我希望这可以工作:
class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new           # create guest user if needed
    if (user.has_role?(:admin))
      can(:manage,:all)
    elsif user.persisted?
      can(:manage,User,:id => user.id)
    end
  end
end
我不确定如果通过
:id => nil
,行为将被定义为什么,这在来宾情况下会发生,但是无论如何,如果您不希望来宾访问列表视图,则您不应该\根本不给那个用户打
can :manage,User
。 总的来说,我发现分配ѭ5使得能力难以推理。     ,嘿,显然这应该可行,但是一些重构可以帮助您发现问题:
require \'spec_helper\'
require \'cancan/matchers\'

describe Ability do
  before(:each) { @user = User.create }

  describe \'guest user\' do
    before(:each) { @ability = Ability.new(nil) }
    subject { @ability } # take advantage of subject

    it \"should not be an admin user\" do
      @user.should_not be_admin
      @user.should be_guest
    end

    it \"should_not show other user\" do
      should_not be_able_to(:read,@user)
    end

    it \"should_not create other user\" do
      should_not be_able_to(:create,User)
    end

    it \"should_not update other user\" do
      should_not be_able_to(:update,@user)
    end

    it \"should_not destroy other user\" do
      should_not be_able_to(:destroy,@user)
    end
  end
end
请注意,我也删除了示例“ 7”。 希望对您有帮助。     ,我已经习惯了回答自己的问题,但是我给@jpemberthy和@Austin Taylor指出了正确的方向。首先(这是装饰性的),我将其添加到我的用户模型中:
class User
  ...
  def self.create_guest
    self.new
  end

  def guest?
    uninitialized?
  end
end
并相应地清理了我的能力模型:
class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.create_guest
    if (user.admin?)
      <admin abilities here>
    elsif (user.guest?)
      <guest abilities here>
    else
      <regular user abilities here>
    end
  end
end
但是真正的解决方法是在我的RSpec测试中。由于用户对电子邮件和密码字段进行了验证,因此我的原始代码为:
before(:each) do
  @user = User.create
end
失败,因此创建了未初始化的ѭ11。由于:id字段为nil,因此Ability子句:
can(:manage,:id => user.id)
来宾用户成功,因为nil == nil(如果有意义)。添加必填字段以满足用户验证(几乎)使所有工作正常。 道德:正如@jpemberthy在他的代码中建议的那样,请始终进行测试以确保您的用户对象具有应有的特权! (我还有另一个关于CanCan的问题,希望它的头脑比这个更少,出现在您附近的StackOverflow主题中……)     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。