Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Allow multiple conditions for callbacks [#1627 state:resolved]

  • Loading branch information...
commit 1e45818a622405e720a4529795f8be2f11660361 1 parent 3b92b14
@josh josh authored
View
9 activesupport/lib/active_support/callbacks.rb
@@ -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
View
42 activesupport/test/callbacks_test.rb
@@ -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)
@@ -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
Please sign in to comment.
Something went wrong with that request. Please try again.