diff options
author | Arthur Neves <arthurnn@gmail.com> | 2014-05-27 00:23:33 -0400 |
---|---|---|
committer | Arthur Neves <arthurnn@gmail.com> | 2014-05-27 00:23:33 -0400 |
commit | 8570f9391d725afae1f3d60bfc5536afc46733b5 (patch) | |
tree | 48d9cce87eab2cfda7e36ff8b2a896f047c6c6e4 /activerecord/lib/active_record | |
parent | 0bdfb4d166f816b104494f0d1adae832aed0421b (diff) | |
download | rails-8570f9391d725afae1f3d60bfc5536afc46733b5.tar.gz rails-8570f9391d725afae1f3d60bfc5536afc46733b5.tar.bz2 rails-8570f9391d725afae1f3d60bfc5536afc46733b5.zip |
Fix redefine a has_and_belongs_to_many inside inherited class
After ad7b5efb55bcc2e0ccd3e7f22a81e984df8676d1, which changed how
has_an_belongs_to_many used to work, we start raising an error when
redefining the same has_an_belongs_to_many association. This commits fix
that regression.
[Fixes #14983]
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r-- | activerecord/lib/active_record/autosave_association.rb | 47 |
1 files changed, 23 insertions, 24 deletions
diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb index 2a7acf6787..74e2a8e6b9 100644 --- a/activerecord/lib/active_record/autosave_association.rb +++ b/activerecord/lib/active_record/autosave_association.rb @@ -147,6 +147,7 @@ module ActiveRecord private def define_non_cyclic_method(name, &block) + return if method_defined?(name) define_method(name) do |*args| result = true; @_already_called ||= {} # Loop prevention for validation of associations @@ -179,30 +180,28 @@ module ActiveRecord validation_method = :"validate_associated_records_for_#{reflection.name}" collection = reflection.collection? - unless method_defined?(save_method) - if collection - before_save :before_save_collection_association - - define_non_cyclic_method(save_method) { save_collection_association(reflection) } - # Doesn't use after_save as that would save associations added in after_create/after_update twice - after_create save_method - after_update save_method - elsif reflection.macro == :has_one - define_method(save_method) { save_has_one_association(reflection) } - # Configures two callbacks instead of a single after_save so that - # the model may rely on their execution order relative to its - # own callbacks. - # - # For example, given that after_creates run before after_saves, if - # we configured instead an after_save there would be no way to fire - # a custom after_create callback after the child association gets - # created. - after_create save_method - after_update save_method - else - define_non_cyclic_method(save_method) { save_belongs_to_association(reflection) } - before_save save_method - end + if collection + before_save :before_save_collection_association + + define_non_cyclic_method(save_method) { save_collection_association(reflection) } + # Doesn't use after_save as that would save associations added in after_create/after_update twice + after_create save_method + after_update save_method + elsif reflection.macro == :has_one + define_method(save_method) { save_has_one_association(reflection) } unless method_defined?(save_method) + # Configures two callbacks instead of a single after_save so that + # the model may rely on their execution order relative to its + # own callbacks. + # + # For example, given that after_creates run before after_saves, if + # we configured instead an after_save there would be no way to fire + # a custom after_create callback after the child association gets + # created. + after_create save_method + after_update save_method + else + define_non_cyclic_method(save_method) { save_belongs_to_association(reflection) } + before_save save_method end if reflection.validate? && !method_defined?(validation_method) |