Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fix bug, when ':dependent => :destroy' option violates foreign key co…

…nstraints, issue #12380
  • Loading branch information...
commit 87d1aba3cba0d9b02490784b3090b0e5c94f56df 1 parent fa91546
@iantropov iantropov authored
View
7 activerecord/CHANGELOG.md
@@ -1,3 +1,10 @@
+* Move 'dependent: :destroy' handling for 'belongs_to'
+ from 'before_destroy' to 'after_destroy' callback chain
+
+ Fix #12380.
+
+ *Ivan Antropov*
+
* Fixed `ActiveRecord::Associations::CollectionAssociation#find`
when using `has_many` association with `:inverse_of` and finding an array of one element,
it should return an array of one element too.
View
17 activerecord/lib/active_record/associations/builder/association.rb
@@ -69,7 +69,10 @@ def define_extensions(model)
end
def define_callbacks(model, reflection)
- add_before_destroy_callbacks(model, name) if options[:dependent]
+ if options[:dependent]
+ check_dependent_options
+ add_destroy_callbacks(model, name)
+ end
Association.extensions.each do |extension|
extension.build model, reflection
end
@@ -110,12 +113,14 @@ def valid_dependent_options
private
- def add_before_destroy_callbacks(model, name)
- unless valid_dependent_options.include? options[:dependent]
- raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{options[:dependent]}"
+ def check_dependent_options
+ unless valid_dependent_options.include? options[:dependent]
+ raise ArgumentError, "The :dependent option must be one of #{valid_dependent_options}, but is :#{options[:dependent]}"
+ end
end
- model.before_destroy lambda { |o| o.association(name).handle_dependency }
- end
+ def add_destroy_callbacks(model, name)
+ model.before_destroy lambda { |o| o.association(name).handle_dependency }
+ end
end
end
View
4 activerecord/lib/active_record/associations/builder/belongs_to.rb
@@ -133,5 +133,9 @@ def add_touch_callbacks(model, reflection)
model.after_touch callback
model.after_destroy callback
end
+
+ def add_destroy_callbacks(model, name)
+ model.after_destroy lambda { |o| o.association(name).handle_dependency }
+ end
end
end
View
6 activerecord/lib/active_record/associations/builder/has_one.rb
@@ -20,8 +20,8 @@ def valid_dependent_options
private
- def add_before_destroy_callbacks(model, name)
- super unless options[:through]
- end
+ def add_destroy_callbacks(model, name)
+ super unless options[:through]
+ end
end
end
View
36 activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -831,3 +831,39 @@ def test_reflect_the_most_recent_change
assert_equal post.author_id, author2.id
end
end
+
+class BelongsToWithForeignKeyTest < ActiveRecord::TestCase
+ def setup
+ ActiveRecord::Schema.define do
+ drop_table :authors, if_exists: true
+ drop_table :author_addresses, if_exists: true
+
+ create_table :author_addresses do |t|
+ end
+
+ exec_query <<-eos
+ create table authors(
+ id int,
+ author_address_id int,
+ name varchar(255),
+ PRIMARY KEY (id),
+ FOREIGN KEY (author_address_id) REFERENCES author_addresses(id)
+ );
+ eos
+ end
+ end
+
+ def teardown
+ ActiveRecord::Schema.define do
+ drop_table :authors, if_exists: true
+ drop_table :author_addresses, if_exists: true
+ end
+ end
+
+ def test_destroy_linked_models
+ address = AuthorAddress.create!
+ author = Author.create! id: 1, name: "Author", author_address_id: address.id
+
+ author.destroy!
+ end
+end

0 comments on commit 87d1aba

Please sign in to comment.
Something went wrong with that request. Please try again.