diff options
author | Jon Leighton <j@jonathanleighton.com> | 2011-12-14 19:20:19 +0000 |
---|---|---|
committer | Jon Leighton <j@jonathanleighton.com> | 2011-12-14 19:20:19 +0000 |
commit | 889e8bee82ea4f75adb6de5badad512d2c615b7f (patch) | |
tree | 8e97f5f816b548e8170bf5e39d2533ccf186f8da | |
parent | 8a37970312815b6ea0b27821f52552df19add8cb (diff) | |
download | rails-889e8bee82ea4f75adb6de5badad512d2c615b7f.tar.gz rails-889e8bee82ea4f75adb6de5badad512d2c615b7f.tar.bz2 rails-889e8bee82ea4f75adb6de5badad512d2c615b7f.zip |
Fix #3672 again (dependent: delete_all perf)
6 files changed, 26 insertions, 9 deletions
diff --git a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb index 30fc44b4c2..0b634ab944 100644 --- a/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb +++ b/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many.rb @@ -18,7 +18,7 @@ module ActiveRecord::Associations::Builder model.send(:include, Module.new { class_eval <<-RUBY, __FILE__, __LINE__ + 1 def destroy_associations - association(#{name.to_sym.inspect}).delete_all + association(#{name.to_sym.inspect}).delete_all_on_destroy super end RUBY diff --git a/activerecord/lib/active_record/associations/builder/has_many.rb b/activerecord/lib/active_record/associations/builder/has_many.rb index d29a525b9e..9c24f40690 100644 --- a/activerecord/lib/active_record/associations/builder/has_many.rb +++ b/activerecord/lib/active_record/associations/builder/has_many.rb @@ -46,10 +46,16 @@ module ActiveRecord::Associations::Builder def define_delete_all_dependency_method name = self.name mixin.redefine_method(dependency_method_name) do + association(name).delete_all_on_destroy + end + end + + def define_nullify_dependency_method + name = self.name + mixin.redefine_method(dependency_method_name) do send(name).delete_all end end - alias :define_nullify_dependency_method :define_delete_all_dependency_method def define_restrict_dependency_method name = self.name diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb index af37909c89..207080973c 100644 --- a/activerecord/lib/active_record/associations/collection_association.rb +++ b/activerecord/lib/active_record/associations/collection_association.rb @@ -152,6 +152,13 @@ module ActiveRecord end end + # Called when the association is declared as :dependent => :delete_all. This is + # an optimised version which avoids loading the records into memory. Not really + # for public consumption. + def delete_all_on_destroy + scoped.delete_all + end + # Destroy all the records from this association. # # See destroy for more info. diff --git a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb index 1f917f58f2..a4cea99372 100644 --- a/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb +++ b/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb @@ -32,6 +32,10 @@ module ActiveRecord record end + # ActiveRecord::Relation#delete_all needs to support joins before we can use a + # SQL-only implementation. + alias delete_all_on_destroy delete_all + private def count_records diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb index c5b90e873a..059e6c77bc 100644 --- a/activerecord/lib/active_record/associations/has_many_association.rb +++ b/activerecord/lib/active_record/associations/has_many_association.rb @@ -89,12 +89,8 @@ module ActiveRecord records.each { |r| r.destroy } update_counter(-records.length) unless inverse_updates_counter_cache? else - scope = scoped - - unless records == load_target - keys = records.map { |r| r[reflection.association_primary_key] } - scope = scoped.where(reflection.association_primary_key => keys) - end + keys = records.map { |r| r[reflection.association_primary_key] } + scope = scoped.where(reflection.association_primary_key => keys) if method == :delete_all update_counter(-scope.delete_all) @@ -103,7 +99,7 @@ module ActiveRecord end end end - + def foreign_key_present? owner.attribute_present?(reflection.association_primary_key) end diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb index 7e6e3be382..9657cb081d 100644 --- a/activerecord/lib/active_record/associations/has_many_through_association.rb +++ b/activerecord/lib/active_record/associations/has_many_through_association.rb @@ -54,6 +54,10 @@ module ActiveRecord record end + # ActiveRecord::Relation#delete_all needs to support joins before we can use a + # SQL-only implementation. + alias delete_all_on_destroy delete_all + private def through_association |