Permalink
Browse files

Fix #3672 again (dependent: delete_all perf)

Conflicts:

	activerecord/lib/active_record/associations/builder/has_many.rb
	activerecord/lib/active_record/associations/has_many_association.rb
  • Loading branch information...
1 parent dced6d6 commit b6ae05e67a2bb07ca4615e7dc2229d3a06b3fdff @jonleighton jonleighton committed Dec 14, 2011
@@ -1,5 +1,10 @@
## Rails 3.1.4 (unreleased) ##
+* Perf fix (second try): don't load records for `has many :dependent =>
+ :delete_all` *GH 3672*
+
+ *Jon Leighton*
+
* Fix accessing `proxy_association` method from an association extension
where the calls are chained. *GH #3890*
@@ -18,7 +18,7 @@ def define_destroy_hook
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
@@ -46,10 +46,16 @@ class << o
def define_delete_all_dependency_method
name = self.name
model.send(:define_method, dependency_method_name) do
+ association(name).delete_all_on_destroy
+ end
+ end
+
+ def define_nullify_dependency_method
+ name = self.name
+ model.send(:define_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
@@ -158,6 +158,13 @@ def delete_all
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.
@@ -32,6 +32,10 @@ def insert_record(record, validate = true, raise = false)
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
@@ -89,12 +89,8 @@ def delete_records(records, method)
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)
@@ -52,6 +52,10 @@ def insert_record(record, validate = true, raise = false)
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

0 comments on commit b6ae05e

Please sign in to comment.