aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael França <rafaelmfranca@gmail.com>2017-07-21 15:37:29 -0400
committerGitHub <noreply@github.com>2017-07-21 15:37:29 -0400
commitc942d3d23486e3de86b3be004ce61cc598b4fd75 (patch)
treec9e5d5305e3ee829f41169f845fa317879182715
parent15ef55efb591e5379486ccf53dd3e13f416564f6 (diff)
parentcb8d8909910e3c6d3b62574e8ce41a024323a00d (diff)
downloadrails-c942d3d23486e3de86b3be004ce61cc598b4fd75.tar.gz
rails-c942d3d23486e3de86b3be004ce61cc598b4fd75.tar.bz2
rails-c942d3d23486e3de86b3be004ce61cc598b4fd75.zip
Merge pull request #29855 from lugray/has_one_destroyed_by_association
Match destroyed_by_association for has_one to has_many
-rw-r--r--activerecord/CHANGELOG.md6
-rw-r--r--activerecord/lib/active_record/associations/has_one_association.rb2
-rw-r--r--activerecord/test/cases/associations/has_one_associations_test.rb34
3 files changed, 42 insertions, 0 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 7eca9c2e2e..ea9f860b95 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,9 @@
+* When a `has_one` association is destroyed by `dependent: destroy`,
+ `destroyed_by_association` will now be set to the reflection, matching the
+ behaviour of `has_many` associations.
+
+ *Lisa Ugray*
+
* Fix `unscoped(where: [columns])` removing the wrong bind values
When the `where` is called on a relation after a `or`, unscoping the column of that later `where` removed
diff --git a/activerecord/lib/active_record/associations/has_one_association.rb b/activerecord/lib/active_record/associations/has_one_association.rb
index 929ea9f567..9a88c1af70 100644
--- a/activerecord/lib/active_record/associations/has_one_association.rb
+++ b/activerecord/lib/active_record/associations/has_one_association.rb
@@ -58,6 +58,7 @@ module ActiveRecord
when :delete
target.delete
when :destroy
+ target.destroyed_by_association = reflection
target.destroy
when :nullify
target.update_columns(reflection.foreign_key => nil) if target.persisted?
@@ -80,6 +81,7 @@ module ActiveRecord
when :delete
target.delete
when :destroy
+ target.destroyed_by_association = reflection
target.destroy
else
nullify_owner_attributes(target)
diff --git a/activerecord/test/cases/associations/has_one_associations_test.rb b/activerecord/test/cases/associations/has_one_associations_test.rb
index ff51a511fc..2eb6cef1d9 100644
--- a/activerecord/test/cases/associations/has_one_associations_test.rb
+++ b/activerecord/test/cases/associations/has_one_associations_test.rb
@@ -690,4 +690,38 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
SpecialAuthor.joins(book: :subscription).where.not(where_clause)
end
end
+
+ class DestroyByParentBook < ActiveRecord::Base
+ self.table_name = "books"
+ belongs_to :author, class_name: "DestroyByParentAuthor"
+ before_destroy :dont, unless: :destroyed_by_association
+
+ def dont
+ throw(:abort)
+ end
+ end
+
+ class DestroyByParentAuthor < ActiveRecord::Base
+ self.table_name = "authors"
+ has_one :book, class_name: "DestroyByParentBook", foreign_key: "author_id", dependent: :destroy
+ end
+
+ test "destroyed_by_association set in child destroy callback on parent destroy" do
+ author = DestroyByParentAuthor.create!(name: "Test")
+ book = DestroyByParentBook.create!(author: author)
+
+ author.destroy
+
+ assert_not DestroyByParentBook.exists?(book.id)
+ end
+
+ test "destroyed_by_association set in child destroy callback on replace" do
+ author = DestroyByParentAuthor.create!(name: "Test")
+ book = DestroyByParentBook.create!(author: author)
+
+ author.book = DestroyByParentBook.create!
+ author.save!
+
+ assert_not DestroyByParentBook.exists?(book.id)
+ end
end