From 6bb8afb45e0fd9243a487e12a0988ac6ea9916bc Mon Sep 17 00:00:00 2001
From: Jon Leighton <j@jonathanleighton.com>
Date: Fri, 10 Aug 2012 16:38:51 +0100
Subject: DRY up handling of dependent option

---
 .../associations/builder/association.rb            | 18 +++++++++++++---
 .../associations/builder/belongs_to.rb             | 20 ++----------------
 .../associations/builder/collection_association.rb |  1 -
 .../active_record/associations/builder/has_many.rb | 24 ++--------------------
 .../active_record/associations/builder/has_one.rb  | 22 +++-----------------
 5 files changed, 22 insertions(+), 63 deletions(-)

diff --git a/activerecord/lib/active_record/associations/builder/association.rb b/activerecord/lib/active_record/associations/builder/association.rb
index 7f929c8395..cae640648b 100644
--- a/activerecord/lib/active_record/associations/builder/association.rb
+++ b/activerecord/lib/active_record/associations/builder/association.rb
@@ -39,6 +39,7 @@ module ActiveRecord::Associations::Builder
     def build
       validate_options
       define_accessors
+      configure_dependency if options[:dependent]
       @reflection = model.create_reflection(macro, name, scope, options, model)
       super # provides an extension point
       @reflection
@@ -75,9 +76,9 @@ module ActiveRecord::Associations::Builder
       end
     end
 
-    def validate_dependent_option(valid_options)
-      unless valid_options.include? options[:dependent]
-        raise ArgumentError, "The :dependent option must be one of #{valid_options}, but is :#{options[:dependent]}"
+    def configure_dependency
+      unless valid_dependent_options.include? options[:dependent]
+        raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{options[:dependent]}"
       end
 
       if options[:dependent] == :restrict
@@ -86,6 +87,17 @@ module ActiveRecord::Associations::Builder
           "provides the same functionality."
         )
       end
+
+      name = self.name
+      mixin.redefine_method("#{macro}_dependent_for_#{name}") do
+        association(name).handle_dependency
+      end
+
+      model.before_destroy "#{macro}_dependent_for_#{name}"
+    end
+
+    def valid_dependent_options
+      raise NotImplementedError
     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 bac21574c7..acfc3073a9 100644
--- a/activerecord/lib/active_record/associations/builder/belongs_to.rb
+++ b/activerecord/lib/active_record/associations/builder/belongs_to.rb
@@ -1,4 +1,3 @@
-
 module ActiveRecord::Associations::Builder
   class BelongsTo < SingularAssociation #:nodoc:
     def macro
@@ -17,7 +16,6 @@ module ActiveRecord::Associations::Builder
       reflection = super
       add_counter_cache_callbacks(reflection) if options[:counter_cache]
       add_touch_callbacks(reflection)         if options[:touch]
-      configure_dependency
       reflection
     end
 
@@ -68,22 +66,8 @@ module ActiveRecord::Associations::Builder
       model.after_destroy(method_name)
     end
 
-    def configure_dependency
-      if dependent = options[:dependent]
-        validate_dependent_option [:destroy, :delete]
-
-        model.send(:class_eval, <<-eoruby, __FILE__, __LINE__ + 1)
-          def #{dependency_method_name}
-            association(:#{name}).handle_dependency
-          end
-        eoruby
-
-        model.after_destroy dependency_method_name
-      end
-    end
-
-    def dependency_method_name
-      "belongs_to_dependent_for_#{name}"
+    def valid_dependent_options
+      [:destroy, :delete]
     end
   end
 end
diff --git a/activerecord/lib/active_record/associations/builder/collection_association.rb b/activerecord/lib/active_record/associations/builder/collection_association.rb
index 6dab00fcc5..40c13dae43 100644
--- a/activerecord/lib/active_record/associations/builder/collection_association.rb
+++ b/activerecord/lib/active_record/associations/builder/collection_association.rb
@@ -1,4 +1,3 @@
-
 module ActiveRecord::Associations::Builder
   class CollectionAssociation < Association #:nodoc:
     CALLBACKS = [:before_add, :after_add, :before_remove, :after_remove]
diff --git a/activerecord/lib/active_record/associations/builder/has_many.rb b/activerecord/lib/active_record/associations/builder/has_many.rb
index a23948c985..ab8225460a 100644
--- a/activerecord/lib/active_record/associations/builder/has_many.rb
+++ b/activerecord/lib/active_record/associations/builder/has_many.rb
@@ -1,4 +1,3 @@
-
 module ActiveRecord::Associations::Builder
   class HasMany < CollectionAssociation #:nodoc:
     def macro
@@ -9,27 +8,8 @@ module ActiveRecord::Associations::Builder
       super + [:primary_key, :dependent, :as, :through, :source, :source_type, :inverse_of]
     end
 
-    def build
-      reflection = super
-      configure_dependency
-      reflection
-    end
-
-    def configure_dependency
-      if dependent = options[:dependent]
-        validate_dependent_option [:destroy, :delete_all, :nullify, :restrict, :restrict_with_error, :restrict_with_exception]
-
-        name = self.name
-        mixin.redefine_method(dependency_method_name) do
-          association(name).handle_dependency
-        end
-
-        model.before_destroy dependency_method_name
-      end
-    end
-
-    def dependency_method_name
-      "has_many_dependent_for_#{name}"
+    def valid_dependent_options
+      [:destroy, :delete_all, :nullify, :restrict, :restrict_with_error, :restrict_with_exception]
     end
   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 bef909a882..0da564f402 100644
--- a/activerecord/lib/active_record/associations/builder/has_one.rb
+++ b/activerecord/lib/active_record/associations/builder/has_one.rb
@@ -1,4 +1,3 @@
-
 module ActiveRecord::Associations::Builder
   class HasOne < SingularAssociation #:nodoc:
     def macro
@@ -15,27 +14,12 @@ module ActiveRecord::Associations::Builder
       !options[:through]
     end
 
-    def build
-      reflection = super
-      configure_dependency unless options[:through]
-      reflection
-    end
-
     def configure_dependency
-      if dependent = options[:dependent]
-        validate_dependent_option [:destroy, :delete, :nullify, :restrict, :restrict_with_error, :restrict_with_exception]
-
-        name = self.name
-        mixin.redefine_method(dependency_method_name) do
-          association(name).handle_dependency
-        end
-
-        model.before_destroy dependency_method_name
-      end
+      super unless options[:through]
     end
 
-    def dependency_method_name
-      "has_one_dependent_for_#{name}"
+    def valid_dependent_options
+      [:destroy, :delete, :nullify, :restrict, :restrict_with_error, :restrict_with_exception]
     end
   end
 end
-- 
cgit v1.2.3