diff --git a/lib/cancan/ability.rb b/lib/cancan/ability.rb index 11e9b4b..07fe5a4 100644 --- a/lib/cancan/ability.rb +++ b/lib/cancan/ability.rb @@ -202,10 +202,7 @@ module CanCan def conditions(action, subject, options = {}) matched = matching_can_definition(action, subject) unless matched.empty? - if matched.any?{|can_definition| - cond = can_definition.conditions - (cond.nil? || cond.empty?) && can_definition.block - } + if matched.any?{|can_definition| can_definition.conditions_empty? && can_definition.block } raise Error, "Cannot determine ability conditions from block for #{action.inspect} #{subject.inspect}" end matched.map{|can_definition| @@ -239,20 +236,19 @@ module CanCan false_cond = subject.send(:sanitize_sql, ['?=?', true, false]) conds.reverse.inject(nil) do |sql, action| behavior, condition = action - if condition && !condition.empty? + if condition && condition != {} condition = "#{subject.send(:sanitize_sql, condition)}" - condition = "not (#{condition})" if behavior == false + case sql + when nil then condition + when true_cond + behavior ? true_cond : "not (#{condition})" + when false_cond + behavior ? condition : false_cond + else + behavior ? "(#{condition}) OR (#{sql})" : "not (#{condition}) AND (#{sql})" + end else - condition = behavior ? true_cond : false_cond - end - case sql - when nil then condition - when true_cond - behavior ? true_cond : condition - when false_cond - behavior ? condition : false_cond - else - behavior ? "(#{condition}) OR (#{sql})" : "#{condition} AND (#{sql})" + behavior ? true_cond : false_cond end end end @@ -262,7 +258,7 @@ module CanCan def association_joins(action, subject) can_definitions = matching_can_definition(action, subject) unless can_definitions.empty? - if can_definitions.any?{|can_definition| can_definition.conditions.nil? && can_definition.block } + if can_definitions.any?{|can_definition| can_definition.conditions_empty? && can_definition.block } raise Error, "Cannot determine association joins from block for #{action.inspect} #{subject.inspect}" end collect_association_joins(can_definitions) @@ -283,7 +279,7 @@ module CanCan can_definition.expand_actions(aliased_actions) if can_definition.matches? action, subject yield can_definition - break if can_definition.conditions.nil? && can_definition.block.nil? + break if can_definition.definitive? end end else diff --git a/lib/cancan/can_definition.rb b/lib/cancan/can_definition.rb index e044ac8..f4a2116 100644 --- a/lib/cancan/can_definition.rb +++ b/lib/cancan/can_definition.rb @@ -51,7 +51,16 @@ module CanCan end end + def definitive? + conditions_empty? && @block.nil? + end + + def conditions_empty? + @conditions == {} || @conditions.nil? + end + def association_joins(conditions = @conditions) + return nil unless conditions.kind_of?(Hash) joins = [] conditions.each do |name, value| if value.kind_of? Hash @@ -81,8 +90,6 @@ module CanCan call_block(action, subject, extra_args) elsif @conditions.kind_of?(Hash) && subject.class != Class matches_conditions?(subject) - elsif [true, false, :_NOT_MATCHES].include? @conditions - @conditions else true end