From 5fd793090abc147867ecbdb2d916eff7e56d732b Mon Sep 17 00:00:00 2001 From: Yura Sokolov Date: Tue, 25 May 2010 14:09:01 +0400 Subject: [PATCH] fix logic error for single `cannot` condition - it should return no records --- lib/cancan/ability.rb | 3 +-- spec/cancan/ability_spec.rb | 30 ++++++++++++++++++++++-------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/lib/cancan/ability.rb b/lib/cancan/ability.rb index 53cb409..2147cbd 100644 --- a/lib/cancan/ability.rb +++ b/lib/cancan/ability.rb @@ -234,12 +234,11 @@ module CanCan true_cond = subject.send(:sanitize_sql, ['?=?', true, true]) false_cond = subject.send(:sanitize_sql, ['?=?', true, false]) - conds.reverse.inject(nil) do |sql, action| + conds.reverse.inject(false_cond) do |sql, action| behavior, condition = action if condition && condition != {} condition = subject.send(:sanitize_sql, condition) case sql - when nil then behavior ? condition : "not (#{condition})" when true_cond behavior ? true_cond : "not (#{condition})" when false_cond diff --git a/spec/cancan/ability_spec.rb b/spec/cancan/ability_spec.rb index d8dd689..cb43747 100644 --- a/spec/cancan/ability_spec.rb +++ b/spec/cancan/ability_spec.rb @@ -239,20 +239,34 @@ describe CanCan::Ability do @ability.sql_conditions(:read, SqlSanitizer).should == { :blocked => false, :user_id => 1 } end - it "should return `not (sql)` for single `cannot` definition" do - @ability.cannot :read, SqlSanitizer, :blocked => true, :user_id => 1 - - @ability.sql_conditions(:read, SqlSanitizer).should == 'not (blocked=true AND user_id=1)' - end - - it "should return `sql` for single `can` definition in front of default cannot condition" do + it "should return `sql` for single `can` definition in front of default `cannot` condition" do @ability.cannot :read, SqlSanitizer @ability.can :read, SqlSanitizer, :blocked => false, :user_id => 1 @ability.sql_conditions(:read, SqlSanitizer).should == 'blocked=false AND user_id=1' end - it "should return `not (sql)` for single `cannot` definition in front of default can condition" do + it "should return `true condition` for single `can` definition in front of default `can` condition" do + @ability.can :read, SqlSanitizer + @ability.can :read, SqlSanitizer, :blocked => false, :user_id => 1 + + @ability.sql_conditions(:read, SqlSanitizer).should == 'true=true' + end + + it "should return `false condition` for single `cannot` definition" do + @ability.cannot :read, SqlSanitizer, :blocked => true, :user_id => 1 + + @ability.sql_conditions(:read, SqlSanitizer).should == 'true=false' + end + + it "should return `false condition` for single `cannot` definition in front of default `cannot` condition" do + @ability.cannot :read, SqlSanitizer + @ability.cannot :read, SqlSanitizer, :blocked => true, :user_id => 1 + + @ability.sql_conditions(:read, SqlSanitizer).should == 'true=false' + end + + it "should return `not (sql)` for single `cannot` definition in front of default `can` condition" do @ability.can :read, SqlSanitizer @ability.cannot :read, SqlSanitizer, :blocked => true, :user_id => 1