diff --git a/Gemfile b/Gemfile index 82993b1..9e69200 100644 --- a/Gemfile +++ b/Gemfile @@ -11,7 +11,7 @@ when "data_mapper" gem "dm-migrations", "~> 1.0.2" when "mongoid" gem "bson_ext", "~> 1.1" - gem "mongoid", "~> 2.0.0.beta.19" + gem "mongoid", "~> 2.0.0.beta.20" else raise "Unknown model adapter: #{ENV["MODEL_ADAPTER"]}" end diff --git a/lib/cancan/model_adapters/mongoid_adapter.rb b/lib/cancan/model_adapters/mongoid_adapter.rb index 70e39e2..24a5956 100644 --- a/lib/cancan/model_adapters/mongoid_adapter.rb +++ b/lib/cancan/model_adapters/mongoid_adapter.rb @@ -16,14 +16,22 @@ module CanCan end def database_records - @model_class.where(conditions) - end - - def conditions - if @rules.size == 0 - false_query + if @rules.size == 0 + @model_class.where(false_query) else - @rules.first.conditions + criteria = @model_class.all + @rules.each do |rule| + criteria = chain_criteria(rule, criteria) + end + criteria + end + end + + def chain_criteria rule, criteria + if rule.base_behavior + criteria.or(rule.conditions) + else + criteria.excludes(rule.conditions) end end diff --git a/spec/cancan/model_adapters/mongoid_adapter_spec.rb b/spec/cancan/model_adapters/mongoid_adapter_spec.rb index 8543990..9281c73 100644 --- a/spec/cancan/model_adapters/mongoid_adapter_spec.rb +++ b/spec/cancan/model_adapters/mongoid_adapter_spec.rb @@ -56,7 +56,7 @@ if ENV["MODEL_ADAPTER"] == "mongoid" lord = MongoidProject.create(:title => 'Lord') dude = MongoidProject.create(:title => 'Dude') - MongoidProject.accessible_by(@ability, :read).should == [sir] + MongoidProject.accessible_by(@ability, :read).entries.should == [sir] end it "should return everything when the defined ability is manage all" do @@ -154,7 +154,24 @@ if ENV["MODEL_ADAPTER"] == "mongoid" @ability.can :read, MongoidProject, :foo => {:bar => 1} MongoidProject.accessible_by(@ability, :read).entries.first.should == obj end + + it "should exclude from the result if set to cannot" do + obj = MongoidProject.create(:bar => 1) + obj2 = MongoidProject.create(:bar => 2) + @ability.can :read, MongoidProject + @ability.cannot :read, MongoidProject, :bar => 2 + MongoidProject.accessible_by(@ability, :read).entries.should == [obj] + end + it "should combine the rules" do + obj = MongoidProject.create(:bar => 1) + obj2 = MongoidProject.create(:bar => 2) + obj3 = MongoidProject.create(:bar => 3) + @ability.can :read, MongoidProject, :bar => 1 + @ability.can :read, MongoidProject, :bar => 2 + MongoidProject.accessible_by(@ability, :read).entries.should =~ [obj, obj2] + end + it "should not allow to fetch records when ability with just block present" do @ability.can :read, MongoidProject do false