1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Refactor configure_dependency_for_has_many to use AssociationCollection#delete_all. It was necessary to change test_before_destroy in lifecycle_test.rb so that it checks topic.replies.size *before* doing the destroy, as afterwards it will now (correctly) be 0.

This commit is contained in:
Jon Leighton 2010-12-30 20:41:02 +00:00
parent 27ea0481bb
commit 38fbfa6390
2 changed files with 24 additions and 41 deletions

View file

@ -1617,11 +1617,13 @@ module ActiveRecord
# Active Record codebase, is meant to allow plugins to define extra
# finder conditions.
def configure_dependency_for_has_many(reflection, extra_conditions = nil)
if reflection.options.include?(:dependent)
if reflection.options[:dependent]
method_name = "has_many_dependent_for_#{reflection.name}"
case reflection.options[:dependent]
when :destroy
method_name = "has_many_dependent_destroy_for_#{reflection.name}".to_sym
define_method(method_name) do
when :destroy, :delete_all, :nullify
define_method(method_name) do
if reflection.options[:dependent] == :destroy
send(reflection.name).each do |o|
# No point in executing the counter update since we're going to destroy the parent anyway
counter_method = ('belongs_to_counter_cache_before_destroy_for_' + self.class.name.downcase).to_sym
@ -1633,35 +1635,23 @@ module ActiveRecord
o.destroy
end
end
before_destroy method_name
when :delete_all
before_destroy do |record|
self.class.send(:delete_all_has_many_dependencies,
record,
reflection.name,
reflection.klass,
reflection.dependent_conditions(record, self.class, extra_conditions))
reflection.klass.send(:with_scope, :find => { :conditions => extra_conditions }) do
# AssociationProxy#delete_all looks at the :dependent option and acts accordingly
send(reflection.name).delete_all
end
when :nullify
before_destroy do |record|
self.class.send(:nullify_has_many_dependencies,
record,
reflection.name,
reflection.klass,
reflection.primary_key_name,
reflection.dependent_conditions(record, self.class, extra_conditions))
end
when :restrict
define_method(method_name) do
unless send(reflection.name).empty?
raise DeleteRestrictionError.new(reflection)
end
when :restrict
method_name = "has_many_dependent_restrict_for_#{reflection.name}".to_sym
define_method(method_name) do
unless send(reflection.name).empty?
raise DeleteRestrictionError.new(reflection)
end
end
before_destroy method_name
else
raise ArgumentError, "The :dependent option expects either :destroy, :delete_all, :nullify or :restrict (#{reflection.options[:dependent].inspect})"
end
else
raise ArgumentError, "The :dependent option expects either :destroy, :delete_all, :nullify or :restrict (#{reflection.options[:dependent].inspect})"
end
before_destroy method_name
end
end
@ -1724,14 +1714,6 @@ module ActiveRecord
end
end
def delete_all_has_many_dependencies(record, reflection_name, association_class, dependent_conditions)
association_class.delete_all(dependent_conditions)
end
def nullify_has_many_dependencies(record, reflection_name, association_class, primary_key_name, dependent_conditions)
association_class.update_all("#{primary_key_name} = NULL", dependent_conditions)
end
mattr_accessor :valid_keys_for_has_many_association
@@valid_keys_for_has_many_association = [
:class_name, :table_name, :foreign_key, :primary_key,

View file

@ -101,9 +101,10 @@ class LifecycleTest < ActiveRecord::TestCase
fixtures :topics, :developers, :minimalistics
def test_before_destroy
original_count = Topic.count
(topic_to_be_destroyed = Topic.find(1)).destroy
assert_equal original_count - (1 + topic_to_be_destroyed.replies.size), Topic.count
topic = Topic.find(1)
assert_difference 'Topic.count', -(1 + topic.replies.size) do
topic.destroy
end
end
def test_auto_observer