diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2011-01-01 11:43:53 -0800 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2011-01-01 11:43:53 -0800 |
commit | 5c7fd8766586dba42fba6fc738a733175dd9d46b (patch) | |
tree | 5f1653b6ca1a307828b10c1013b84e1e4e41a97e /activerecord/lib/active_record/associations.rb | |
parent | 171172f324444a9ea9c98e4f3663c6e401fb3ec7 (diff) | |
parent | 12675988813e82ac30f7c0e0008c12c4cf5d8cdc (diff) | |
download | rails-5c7fd8766586dba42fba6fc738a733175dd9d46b.tar.gz rails-5c7fd8766586dba42fba6fc738a733175dd9d46b.tar.bz2 rails-5c7fd8766586dba42fba6fc738a733175dd9d46b.zip |
Merge remote branch 'jonleighton/association_fixes' into fuuu
* jonleighton/association_fixes:
Rename AssociationReflection#primary_key_name to foreign_key, since the options key which it relates to is :foreign_key
Support for :counter_cache on polymorphic belongs_to
Refactor BelongsToAssociation to allow BelongsToPolymorphicAssociation to inherit from it
Specify the STI type condition using SQL IN rather than a whole load of ORs. Required a fix to ActiveRecord::Relation#merge for properly merging create_with_value. This also fixes a situation where the type condition was appearing twice in the resultant SQL query.
Verify that when has_many associated objects are destroyed via :dependent => :destroy, when the parent is destroyed, the callbacks are run
Get rid of extra_conditions param from configure_dependency_for_has_many. I can't see a particularly plausible argument for this being used by plugins, and if they really want they can just redefine the callback or whatever. Note also that before my recent commit the extra_conditions param was completely ignored for :dependent => :destroy.
And owner_quoted_id can go too
Now we can drop-kick AssociationReflection#dependent_conditions into oblivion.
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.
Diffstat (limited to 'activerecord/lib/active_record/associations.rb')
-rw-r--r-- | activerecord/lib/active_record/associations.rb | 68 |
1 files changed, 22 insertions, 46 deletions
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index b49cf8de95..9a4f6d4dfd 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1612,16 +1612,14 @@ module ActiveRecord # - set the foreign key to NULL if the option is set to :nullify # - do not delete the parent record if there is any child record if the # option is set to :restrict - # - # The +extra_conditions+ parameter, which is not used within the main - # 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) + def configure_dependency_for_has_many(reflection) + 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 +1631,21 @@ 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)) - 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 - 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 + + # AssociationProxy#delete_all looks at the :dependent option and acts accordingly + send(reflection.name).delete_all + end + when :restrict + define_method(method_name) do + unless send(reflection.name).empty? + raise DeleteRestrictionError.new(reflection) 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 @@ -1686,7 +1670,7 @@ module ActiveRecord class_eval <<-eoruby, __FILE__, __LINE__ + 1 def #{method_name} association = #{reflection.name} - association.update_attribute(#{reflection.primary_key_name.inspect}, nil) if association + association.update_attribute(#{reflection.foreign_key.inspect}, nil) if association end eoruby when :restrict @@ -1724,14 +1708,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, @@ -1806,7 +1782,7 @@ module ActiveRecord reflection = create_reflection(:has_and_belongs_to_many, association_id, options, self) - if reflection.association_foreign_key == reflection.primary_key_name + if reflection.association_foreign_key == reflection.foreign_key raise HasAndBelongsToManyAssociationForeignKeyNeeded.new(reflection) end |