0

cancan gemを使用していますが、いくつか問題が発生しました。ロールが割り当てられていないユーザーに対して失敗するいくつかの簡単なテストを作成しました。Ability クラス内では、ユーザーが :admin の役割を持っている場合にのみ、ユーザーが他のユーザーを管理できると言っていることがわかります。コメントで指摘されているように、そのブロックは呼び出されません。

缶にブロックを渡すと缶カンジェムに?メソッドはそれをルールに追加し、缶を呼び出すときに呼び出されますか? ただし、渡されるオブジェクトのクラスが 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

カンカンはかなり人気があるので、私は何か間違ったことをしているという事実にお金をかけています. どんな助けでも大歓迎です。

4

2 に答える 2

0

以下のコードは、Ability クラスに必要なもののようです。

can :manage, User if user.has_role? :admin 
于 2013-03-02T07:36:25.187 に答える