Add support for Mongoid::Criteria Symbol extensions (:age.gt => 10) along with specs.
This commit is contained in:
parent
be74df0548
commit
ab82dcbc8f
|
@ -18,6 +18,8 @@ Gem::Specification.new do |s|
|
||||||
s.add_development_dependency 'mongoid', '~> 2.0.0.beta.19'
|
s.add_development_dependency 'mongoid', '~> 2.0.0.beta.19'
|
||||||
s.add_development_dependency 'bson_ext', '~> 1.1'
|
s.add_development_dependency 'bson_ext', '~> 1.1'
|
||||||
|
|
||||||
|
s.add_development_dependency 'ruby-debug'
|
||||||
|
|
||||||
s.rubyforge_project = s.name
|
s.rubyforge_project = s.name
|
||||||
s.required_rubygems_version = ">= 1.3.4"
|
s.required_rubygems_version = ">= 1.3.4"
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,6 +26,42 @@ module CanCan
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# customize to handle Mongoid queries in ability definitions conditions
|
||||||
|
class CanDefinition
|
||||||
|
def matches_conditions_hash?(subject, conditions = @conditions)
|
||||||
|
if subject.class.include?(Mongoid::Document) # Mongoid Criteria are simpler to check than normal conditions hashes
|
||||||
|
if conditions.empty? # When no conditions are given, true should be returned.
|
||||||
|
# The default CanCan behavior relies on the fact that conditions.all? will return true when conditions is empty
|
||||||
|
# The way ruby handles all? for empty hashes can be unexpected:
|
||||||
|
# {}.all?{|a| a == 5}
|
||||||
|
# => true
|
||||||
|
# {}.all?{|a| a != 5}
|
||||||
|
# => true
|
||||||
|
true
|
||||||
|
else
|
||||||
|
subject.class.where(conditions).include?(subject) # just use Mongoid's where function
|
||||||
|
end
|
||||||
|
else
|
||||||
|
conditions.all? do |name, value|
|
||||||
|
attribute = subject.send(name)
|
||||||
|
if value.kind_of?(Hash)
|
||||||
|
if attribute.kind_of? Array
|
||||||
|
attribute.any? { |element| matches_conditions_hash? element, value }
|
||||||
|
else
|
||||||
|
matches_conditions_hash? attribute, value
|
||||||
|
end
|
||||||
|
elsif value.kind_of?(Array) || value.kind_of?(Range)
|
||||||
|
value.include? attribute
|
||||||
|
else
|
||||||
|
attribute == value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module MongoidAdditions
|
module MongoidAdditions
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
# Returns a scope which fetches only the records that the passed ability
|
# Returns a scope which fetches only the records that the passed ability
|
||||||
|
|
|
@ -3,11 +3,14 @@ require 'mongoid'
|
||||||
|
|
||||||
class MongoidCategory
|
class MongoidCategory
|
||||||
include Mongoid::Document
|
include Mongoid::Document
|
||||||
|
include CanCan::MongoidAdditions
|
||||||
|
|
||||||
references_many :mongoid_projects
|
references_many :mongoid_projects
|
||||||
end
|
end
|
||||||
|
|
||||||
class MongoidProject
|
class MongoidProject
|
||||||
include Mongoid::Document
|
include Mongoid::Document
|
||||||
|
include CanCan::MongoidAdditions
|
||||||
|
|
||||||
referenced_in :mongoid_category
|
referenced_in :mongoid_category
|
||||||
|
|
||||||
|
@ -36,9 +39,7 @@ end
|
||||||
|
|
||||||
describe CanCan::MongoidAdditions do
|
describe CanCan::MongoidAdditions do
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@model_class = Class.new(MongoidProject)
|
@model_class = MongoidProject
|
||||||
stub(@model_class).scoped { :scoped_stub }
|
|
||||||
@model_class.send(:include, CanCan::MongoidAdditions)
|
|
||||||
@ability = Object.new
|
@ability = Object.new
|
||||||
@ability.extend(CanCan::Ability)
|
@ability.extend(CanCan::Ability)
|
||||||
end
|
end
|
||||||
|
@ -53,6 +54,53 @@ describe CanCan::MongoidAdditions do
|
||||||
@model_class.accessible_by(@ability, :read).should == []
|
@model_class.accessible_by(@ability, :read).should == []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "Mongoid::Criteria where clause Symbol extensions using MongoDB expressions" do
|
||||||
|
it "should handle :field.in" do
|
||||||
|
obj = @model_class.create :title => 'Sir'
|
||||||
|
@ability.can :read, @model_class, :title.in => ["Sir", "Madam"]
|
||||||
|
@ability.can?(:read, obj).should == true
|
||||||
|
|
||||||
|
obj2 = @model_class.create :title => 'Lord'
|
||||||
|
@ability.can?(:read, obj2).should == false
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should handle :field.nin" do
|
||||||
|
obj = @model_class.create :title => 'Sir'
|
||||||
|
@ability.can :read, @model_class, :title.nin => ["Lord", "Madam"]
|
||||||
|
@ability.can?(:read, obj).should == true
|
||||||
|
|
||||||
|
obj2 = @model_class.create :title => 'Lord'
|
||||||
|
@ability.can?(:read, obj2).should == false
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should handle :field.size" do
|
||||||
|
obj = @model_class.create :titles => ['Palatin', 'Margrave']
|
||||||
|
@ability.can :read, @model_class, :titles.size => 2
|
||||||
|
@ability.can?(:read, obj).should == true
|
||||||
|
|
||||||
|
obj2 = @model_class.create :titles => ['Palatin', 'Margrave', 'Marquis']
|
||||||
|
@ability.can?(:read, obj2).should == false
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should handle :field.exists" do
|
||||||
|
obj = @model_class.create :titles => ['Palatin', 'Margrave']
|
||||||
|
@ability.can :read, @model_class, :titles.exists => true
|
||||||
|
@ability.can?(:read, obj).should == true
|
||||||
|
|
||||||
|
obj2 = @model_class.create
|
||||||
|
@ability.can?(:read, obj2).should == false
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should handle :field.gt" do
|
||||||
|
obj = @model_class.create :age => 50
|
||||||
|
@ability.can :read, @model_class, :age.gt => 45
|
||||||
|
@ability.can?(:read, obj).should == true
|
||||||
|
|
||||||
|
obj2 = @model_class.create :age => 40
|
||||||
|
@ability.can?(:read, obj2).should == false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it "should call where with matching ability conditions" do
|
it "should call where with matching ability conditions" do
|
||||||
@ability.can :read, @model_class, :foo => {:bar => 1}
|
@ability.can :read, @model_class, :foo => {:bar => 1}
|
||||||
@model_class.accessible_by(@ability, :read).should == @model_class.where(:foos => { :bar => 1 })
|
@model_class.accessible_by(@ability, :read).should == @model_class.where(:foos => { :bar => 1 })
|
||||||
|
|
Loading…
Reference in New Issue
Block a user