From ea8181b65637af65db5bb834f1c86df57969516e Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Fri, 10 Aug 2012 16:00:09 +0100 Subject: move dependency logic out of generated methods --- .../associations/belongs_to_association.rb | 5 ++++ .../associations/builder/association.rb | 24 ------------------ .../associations/builder/belongs_to.rb | 13 ++++++---- .../active_record/associations/builder/has_many.rb | 29 +++------------------- .../active_record/associations/builder/has_one.rb | 18 ++++++-------- .../associations/has_many_association.rb | 22 ++++++++++++++++ .../associations/has_one_association.rb | 18 ++++++++++++++ 7 files changed, 64 insertions(+), 65 deletions(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb index ddfc6f6c05..75f72c1a46 100644 --- a/activerecord/lib/active_record/associations/belongs_to_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_association.rb @@ -2,6 +2,11 @@ module ActiveRecord # = Active Record Belongs To Associations module Associations class BelongsToAssociation < SingularAssociation #:nodoc: + + def handle_dependency + target.send(options[:dependent]) if load_target + end + def replace(record) raise_on_type_mismatch(record) if record diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb index 14e8f9f8f5..7df666418c 100644 --- a/activerecord/lib/active_record/associations/builder/association.rb +++ b/activerecord/lib/active_record/associations/builder/association.rb @@ -89,29 +89,5 @@ module ActiveRecord::Associations::Builder ) end end - - def define_restrict_with_exception_dependency_method - name = self.name - mixin.redefine_method(dependency_method_name) do - has_one_macro = association(name).reflection.macro == :has_one - if has_one_macro ? !send(name).nil? : send(name).exists? - raise ActiveRecord::DeleteRestrictionError.new(name) - end - end - end - alias define_restrict_dependency_method define_restrict_with_exception_dependency_method - - def define_restrict_with_error_dependency_method - name = self.name - mixin.redefine_method(dependency_method_name) do - has_one_macro = association(name).reflection.macro == :has_one - if has_one_macro ? !send(name).nil? : send(name).exists? - key = has_one_macro ? "one" : "many" - errors.add(:base, :"restrict_dependent_destroy.#{key}", - :record => self.class.human_attribute_name(name).downcase) - false - end - end - end end end diff --git a/activerecord/lib/active_record/associations/builder/belongs_to.rb b/activerecord/lib/active_record/associations/builder/belongs_to.rb index b9642f556d..313a8ea3d0 100644 --- a/activerecord/lib/active_record/associations/builder/belongs_to.rb +++ b/activerecord/lib/active_record/associations/builder/belongs_to.rb @@ -74,15 +74,18 @@ module ActiveRecord::Associations::Builder if dependent = options[:dependent] validate_dependent_option [:destroy, :delete] - method_name = "belongs_to_dependent_#{dependent}_for_#{name}" model.send(:class_eval, <<-eoruby, __FILE__, __LINE__ + 1) - def #{method_name} - association = #{name} - association.#{dependent} if association + def #{dependency_method_name} + association(:#{name}).handle_dependency end eoruby - model.after_destroy method_name + + model.after_destroy dependency_method_name end end + + def dependency_method_name + "belongs_to_dependent_for_#{name}" + end end end diff --git a/activerecord/lib/active_record/associations/builder/has_many.rb b/activerecord/lib/active_record/associations/builder/has_many.rb index ee52e873d0..309612f41c 100644 --- a/activerecord/lib/active_record/associations/builder/has_many.rb +++ b/activerecord/lib/active_record/associations/builder/has_many.rb @@ -20,34 +20,13 @@ module ActiveRecord::Associations::Builder def configure_dependency if dependent = options[:dependent] validate_dependent_option [:destroy, :delete_all, :nullify, :restrict, :restrict_with_error, :restrict_with_exception] - send("define_#{dependent}_dependency_method") - model.before_destroy dependency_method_name - end - end - def define_destroy_dependency_method - name = self.name - mixin.redefine_method(dependency_method_name) do - send(name).each do |o| - # No point in executing the counter update since we're going to destroy the parent anyway - o.mark_for_destruction + name = self.name + mixin.redefine_method(dependency_method_name) do + association(name).handle_dependency end - send(name).delete_all - end - end - - def define_delete_all_dependency_method - name = self.name - mixin.redefine_method(dependency_method_name) do - association(name).delete_all - end - end - - def define_nullify_dependency_method - name = self.name - mixin.redefine_method(dependency_method_name) do - send(name).delete_all + model.before_destroy dependency_method_name end end diff --git a/activerecord/lib/active_record/associations/builder/has_one.rb b/activerecord/lib/active_record/associations/builder/has_one.rb index e5d57b2990..ab39230e12 100644 --- a/activerecord/lib/active_record/associations/builder/has_one.rb +++ b/activerecord/lib/active_record/associations/builder/has_one.rb @@ -26,22 +26,18 @@ module ActiveRecord::Associations::Builder def configure_dependency if dependent = options[:dependent] validate_dependent_option [:destroy, :delete, :nullify, :restrict, :restrict_with_error, :restrict_with_exception] - send("define_#{dependent}_dependency_method") - model.before_destroy dependency_method_name - end - end - def define_destroy_dependency_method - name = self.name - mixin.redefine_method(dependency_method_name) do - association(name).delete + name = self.name + mixin.redefine_method(dependency_method_name) do + association(name).handle_dependency + end + + model.before_destroy dependency_method_name end end - alias :define_delete_dependency_method :define_destroy_dependency_method - alias :define_nullify_dependency_method :define_destroy_dependency_method def dependency_method_name - "has_one_dependent_#{options[:dependent]}_for_#{name}" + "has_one_dependent_for_#{name}" end end end diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb index 7a363c896e..74864d271f 100644 --- a/activerecord/lib/active_record/associations/has_many_association.rb +++ b/activerecord/lib/active_record/associations/has_many_association.rb @@ -7,6 +7,28 @@ module ActiveRecord # is provided by its child HasManyThroughAssociation. class HasManyAssociation < CollectionAssociation #:nodoc: + def handle_dependency + case options[:dependent] + when :restrict, :restrict_with_exception + raise ActiveRecord::DeleteRestrictionError.new(reflection.name) unless empty? + + when :restrict_with_error + unless empty? + record = klass.human_attribute_name(reflection.name).downcase + owner.errors.add(:base, :"restrict_dependent_destroy.many", record: record) + false + end + + else + if options[:dependent] == :destroy + # No point in executing the counter update since we're going to destroy the parent anyway + load_target.each(&:mark_for_destruction) + end + + delete_all + end + end + def insert_record(record, validate = true, raise = false) set_owner_attributes(record) diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb index 3b96ca5eb8..dd7da59a86 100644 --- a/activerecord/lib/active_record/associations/has_one_association.rb +++ b/activerecord/lib/active_record/associations/has_one_association.rb @@ -3,6 +3,24 @@ module ActiveRecord # = Active Record Belongs To Has One Association module Associations class HasOneAssociation < SingularAssociation #:nodoc: + + def handle_dependency + case options[:dependent] + when :restrict, :restrict_with_exception + raise ActiveRecord::DeleteRestrictionError.new(reflection.name) if load_target + + when :restrict_with_error + if load_target + record = klass.human_attribute_name(reflection.name).downcase + owner.errors.add(:base, :"restrict_dependent_destroy.one", record: record) + false + end + + else + delete + end + end + def replace(record, save = true) raise_on_type_mismatch(record) if record load_target -- cgit v1.2.3