consider specificity when finding relevant rules so generic rules will not override specific ones - closes #321

This commit is contained in:
Ryan Bates
2011-09-28 15:34:08 -07:00
parent 1fb2c0160c
commit 6de9e4675a
5 changed files with 37 additions and 10 deletions
+6 -2
View File
@@ -299,10 +299,14 @@ module CanCan
# Returns an array of Rule instances which match the action and subject
# This does not take into consideration any hash conditions or block statements
def relevant_rules(action, subject, attribute = nil)
rules.reverse.select do |rule|
specificity = 0
rules.reverse.each_with_object([]) do |rule, relevant_rules|
rule.expanded_actions = expand_aliases(:actions, rule.actions)
rule.expanded_subjects = expand_aliases(:subjects, rule.subjects)
rule.relevant? action, subject, attribute
if rule.relevant?(action, subject, attribute) && rule.specificity >= specificity
specificity = rule.specificity if rule.base_behavior
relevant_rules << rule
end
end
end
+13 -6
View File
@@ -44,23 +44,23 @@ module CanCan
end
def only_block?
conditions_empty? && !@block.nil?
!conditions? && !@block.nil?
end
def only_raw_sql?
@block.nil? && !conditions_empty? && !@conditions.kind_of?(Hash)
@block.nil? && conditions? && !@conditions.kind_of?(Hash)
end
def attributes?
@attributes.present?
end
def instance_conditions?
@block || !conditions_empty?
def conditions?
@conditions.present?
end
def conditions_empty?
@conditions == {} || @conditions.nil?
def instance_conditions?
@block || conditions?
end
def associations_hash(conditions = @conditions)
@@ -79,6 +79,13 @@ module CanCan
attributes
end
def specificity
specificity = 1
specificity += 1 if attributes? || conditions?
specificity += 2 unless base_behavior
specificity
end
private
def subject_object?(subject)