CanCan似乎忽略了阻止

时间:2013-03-02 05:14:05

标签: ruby-on-rails cancan

我正在使用 cancan gem,但遇到了一些问题。我写了一些简单的测试,对于没有分配角色的用户而言失败了。可以看出,在Ability类中,我试图说只有当用户具有以下角色时,用户才能管理其他用户:admin。正如评论所指出的,该块永远不会被调用。

当你将一个街区传给罐头时,在康康舞宝石中?它将它添加到规则中,然后在调用can时调用该规则?方法,除非传入的对象的类是Class。因此,当我执行下面的测试时,它失败了,因为我传递的是User和User.class == Class。

it { should_not be_able_to(:create, User) }
or
it "cannot create a User" do
  expect(ability.cannot? :create, User).to be_true
end

考虑到这一点,如果我编写一个测试特定用户的测试,测试通过:

it { should_not be_able_to(:edit, FactoryGirl.create(:user) ) }   # passes, but...

但是当您列出或创建时,这没有任何意义:

it { should_not be_able_to(:create, FactoryGirl.create(:user) ) }  # yuck

我想你可以使用

it { should_not be_able_to(:create, User.new ) }  # but that is still full of suck

参考代码:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new

    can :manage, User do |u|
      # this block never gets called
      user.has_role? :admin
    end
  end
end


describe "user without roles" do
  subject { ability }
  let(:ability) { Ability.new create(:user) }

  it { should_not be_able_to(:manage, User) }  # passes
  it { should_not be_able_to(:index, User) }   # all the rest fail
  it { should_not be_able_to(:new, User) }
  it { should_not be_able_to(:edit, User) }
  it { should_not be_able_to(:create, User) }
  it { should_not be_able_to(:update, User) }

end

# CANCAN CODE
# https://github.com/ryanb/cancan/blob/c88cb8f4593148f99e15627d23fbf67116dd8be2/lib/cancan/can_definition.rb#L32
def matches_conditions?(action, subject, extra_args)
  if @match_all
    call_block_with_all(action, subject, extra_args)

  ## The condition in question, this is where I should go to
  ## subject -> User
  ## User.class -> Class
  elsif @block && !subject_class?(subject)
    @block.call(subject, *extra_args)
  elsif @conditions.kind_of?(Hash) && subject.kind_of?(Hash)
    nested_subject_matches_conditions?(subject)
  elsif @conditions.kind_of?(Hash) && !subject_class?(subject)
    matches_conditions_hash?(subject)
  else
    @base_behavior
  end
end

# User class returns true
def subject_class?(subject)
  (subject.kind_of?(Hash) ? subject.values.first : subject).class == Class
end

因为康康很受欢迎,所以我把钱放在我做错事的事实上。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

看起来下面的代码是我在Ability类中应该拥有的:

can :manage, User if user.has_role? :admin 

答案 1 :(得分:0)

你不使用| u |在您的区块中:

can :manage, User do |u|
  u.has_role? :admin
end

尝试使用https://gist.github.com/fotinakis/3a532a0929f64b4b5352进行测试。它们看起来如下:

context "user without roles" do
  it "can view everything" do
    expect(@guest).to have_ability(:read, for: "all")
  end

  it "cannot edit or delete anything" do
    expect(@guest).to_not have_ability(:manage, for: "all")
  end
end