can? should only go to db if there are mongoid criteria in the conditions.

Easier to just do a simple comparison on the object in memory
than to search the database.  Also this allows method calls
and other attributes that might not be found in the database.
This commit is contained in:
Tyler Gannon
2010-11-15 19:43:54 -08:00
parent dbcd93e095
commit f6aaa581ef
4 changed files with 43 additions and 28 deletions

View File

@@ -36,37 +36,28 @@ module CanCan
end
# customize to handle Mongoid queries in ability definitions conditions
# Mongoid Criteria are simpler to check than normal conditions hashes
# 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
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
def matches_conditions_hash_with_mongoid_subject?(subject, conditions = @conditions)
if subject.class.include?(Mongoid::Document) && conditions.any?{|k,v| !k.kind_of?(Symbol)}
if conditions.empty?
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
matches_conditions_hash_without_mongoid_subject? subject, conditions
end
end
alias_method :matches_conditions_hash_without_mongoid_subject?, :matches_conditions_hash?
alias_method :matches_conditions_hash?, :matches_conditions_hash_with_mongoid_subject?
end
@@ -114,4 +105,4 @@ if defined? Mongoid
end
end
end
end
end