diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2012-12-21 17:39:03 -0300 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2012-12-21 17:39:03 -0300 |
commit | ecc77515754b15e5a2d794832ec4a5286cabdfe5 (patch) | |
tree | ee40fb03408f925bc169dc8fba0751b926d28912 /activesupport/lib | |
parent | bda1937f285d3114c2b2300b86c23f19db88de79 (diff) | |
parent | 4a9644a0d94a88896e1ebd3329b8f796fbd053d1 (diff) | |
download | rails-ecc77515754b15e5a2d794832ec4a5286cabdfe5.tar.gz rails-ecc77515754b15e5a2d794832ec4a5286cabdfe5.tar.bz2 rails-ecc77515754b15e5a2d794832ec4a5286cabdfe5.zip |
Merge pull request #7376 from dmitriy-kiriyenko/fix-double-callback-in-same-statement
Prevent callback from being set twice.
Conflicts:
activesupport/CHANGELOG.md
Diffstat (limited to 'activesupport/lib')
-rw-r--r-- | activesupport/lib/active_support/callbacks.rb | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index e772a297fc..e3e1845868 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -134,6 +134,10 @@ module ActiveSupport @kind == _kind && @filter == _filter end + def duplicates?(other) + matches?(other.kind, other.filter) + end + def _update_filter(filter_options, new_options) filter_options[:if].concat(Array(new_options[:unless])) if new_options.key?(:unless) filter_options[:unless].concat(Array(new_options[:if])) if new_options.key?(:if) @@ -328,6 +332,30 @@ module ActiveSupport method.join("\n") end + def append(*callbacks) + callbacks.each { |c| append_one(c) } + end + + def prepend(*callbacks) + callbacks.each { |c| prepend_one(c) } + end + + private + + def append_one(callback) + remove_duplicates(callback) + push(callback) + end + + def prepend_one(callback) + remove_duplicates(callback) + unshift(callback) + end + + def remove_duplicates(callback) + delete_if { |c| callback.duplicates?(c) } + end + end module ClassMethods @@ -421,11 +449,7 @@ module ActiveSupport Callback.new(chain, filter, type, options.dup, self) end - filters.each do |filter| - chain.delete_if {|c| c.matches?(type, filter) } - end - - options[:prepend] ? chain.unshift(*(mapped.reverse)) : chain.push(*mapped) + options[:prepend] ? chain.prepend(*mapped) : chain.append(*mapped) target.send("_#{name}_callbacks=", chain) end |