Skip to content

Commit

Permalink
Allow multiple conditions for callbacks [#1627 state:resolved]
Browse files Browse the repository at this point in the history
  • Loading branch information
josh committed Dec 28, 2008
1 parent 3b92b14 commit 1e45818
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 8 deletions.
9 changes: 2 additions & 7 deletions activesupport/lib/active_support/callbacks.rb
Expand Up @@ -192,13 +192,8 @@ def evaluate_method(method, *args, &block)
end

def should_run_callback?(*args)
if options[:if]
evaluate_method(options[:if], *args)
elsif options[:unless]
!evaluate_method(options[:unless], *args)
else
true
end
[options[:if]].flatten.compact.all? { |a| evaluate_method(a, *args) } &&
![options[:unless]].flatten.compact.any? { |a| evaluate_method(a, *args) }
end
end

Expand Down
42 changes: 41 additions & 1 deletion activesupport/test/callbacks_test.rb
Expand Up @@ -53,10 +53,41 @@ def save
end

class ConditionalPerson < Record
# proc
before_save Proc.new { |r| r.history << [:before_save, :proc] }, :if => Proc.new { |r| true }
before_save Proc.new { |r| r.history << "b00m" }, :if => Proc.new { |r| false }
before_save Proc.new { |r| r.history << [:before_save, :proc] }, :unless => Proc.new { |r| false }
before_save Proc.new { |r| r.history << "b00m" }, :unless => Proc.new { |r| true }
# symbol
before_save Proc.new { |r| r.history << [:before_save, :symbol] }, :if => :yes
before_save Proc.new { |r| r.history << "b00m" }, :if => :no
before_save Proc.new { |r| r.history << [:before_save, :symbol] }, :unless => :no
before_save Proc.new { |r| r.history << "b00m" }, :unless => :yes
# string
before_save Proc.new { |r| r.history << [:before_save, :string] }, :if => 'yes'
before_save Proc.new { |r| r.history << "b00m" }, :if => 'no'
before_save Proc.new { |r| r.history << [:before_save, :string] }, :unless => 'no'
before_save Proc.new { |r| r.history << "b00m" }, :unless => 'yes'
# Array with conditions
before_save Proc.new { |r| r.history << [:before_save, :symbol_array] }, :if => [:yes, :other_yes]
before_save Proc.new { |r| r.history << "b00m" }, :if => [:yes, :no]
before_save Proc.new { |r| r.history << [:before_save, :symbol_array] }, :unless => [:no, :other_no]
before_save Proc.new { |r| r.history << "b00m" }, :unless => [:yes, :no]
# Combined if and unless
before_save Proc.new { |r| r.history << [:before_save, :combined_symbol] }, :if => :yes, :unless => :no
before_save Proc.new { |r| r.history << "b00m" }, :if => :yes, :unless => :yes
# Array with different types of conditions
before_save Proc.new { |r| r.history << [:before_save, :symbol_proc_string_array] }, :if => [:yes, Proc.new { |r| true }, 'yes']
before_save Proc.new { |r| r.history << "b00m" }, :if => [:yes, Proc.new { |r| true }, 'no']
# Array with different types of conditions comibned if and unless
before_save Proc.new { |r| r.history << [:before_save, :combined_symbol_proc_string_array] },
:if => [:yes, Proc.new { |r| true }, 'yes'], :unless => [:no, 'no']
before_save Proc.new { |r| r.history << "b00m" }, :if => [:yes, Proc.new { |r| true }, 'no'], :unless => [:no, 'no']

def yes; true; end
def other_yes; true; end
def no; false; end
def other_no; false; end

def save
run_callbacks(:before_save)
Expand Down Expand Up @@ -90,7 +121,16 @@ def test_save_conditional_person
person.save
assert_equal [
[:before_save, :proc],
[:before_save, :proc]
[:before_save, :proc],
[:before_save, :symbol],
[:before_save, :symbol],
[:before_save, :string],
[:before_save, :string],
[:before_save, :symbol_array],
[:before_save, :symbol_array],
[:before_save, :combined_symbol],
[:before_save, :symbol_proc_string_array],
[:before_save, :combined_symbol_proc_string_array]
], person.history
end
end
Expand Down

0 comments on commit 1e45818

Please sign in to comment.