Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #32119 from fegorodscy/master
Fix dependence on has_one/belongs_to relationships

(cherry picked from commit 13e35a5)
  • Loading branch information
pixeltrix committed Mar 6, 2018
1 parent 73c1627 commit b0fc04a
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 1 deletion.
7 changes: 7 additions & 0 deletions activerecord/CHANGELOG.md
@@ -1,3 +1,10 @@
* Fix `dependent: :destroy` issue for has_one/belongs_to relationship where
the parent class was getting deleted when the child was not.

Fixes #32022.

*Fernando Gorodscy*

* Whitelist `NULLS FIRST` and `NULLS LAST` in order clauses too.

*Xavier Noria*
Expand Down
Expand Up @@ -5,7 +5,15 @@ module Associations
# = Active Record Belongs To Association
class BelongsToAssociation < SingularAssociation #:nodoc:
def handle_dependency
target.send(options[:dependent]) if load_target
return unless load_target

case options[:dependent]
when :destroy
target.destroy
raise ActiveRecord::Rollback unless target.destroyed?
else
target.send(options[:dependent])
end
end

def replace(record)
Expand Down
Expand Up @@ -60,6 +60,7 @@ def delete(method = options[:dependent])
when :destroy
target.destroyed_by_association = reflection
target.destroy
throw(:abort) unless target.destroyed?
when :nullify
target.update_columns(reflection.foreign_key => nil) if target.persisted?
end
Expand Down
Expand Up @@ -931,6 +931,30 @@ def test_belongs_to_invalid_dependent_option_raises_exception
assert_equal error.message, "The :dependent option must be one of [:destroy, :delete], but is :nullify"
end

class DestroyableBook < ActiveRecord::Base
self.table_name = "books"
belongs_to :author, class_name: "UndestroyableAuthor", dependent: :destroy
end

class UndestroyableAuthor < ActiveRecord::Base
self.table_name = "authors"
has_one :book, class_name: "DestroyableBook", foreign_key: "author_id"
before_destroy :dont

def dont
throw(:abort)
end
end

def test_dependency_should_halt_parent_destruction
author = UndestroyableAuthor.create!(name: "Test")
book = DestroyableBook.create!(author: author)

assert_no_difference ["UndestroyableAuthor.count", "DestroyableBook.count"] do
assert_not book.destroy
end
end

def test_attributes_are_being_set_when_initialized_from_belongs_to_association_with_where_clause
new_firm = accounts(:signals37).build_firm(name: "Apple")
assert_equal new_firm.name, "Apple"
Expand Down
24 changes: 24 additions & 0 deletions activerecord/test/cases/associations/has_one_associations_test.rb
Expand Up @@ -725,4 +725,28 @@ class DestroyByParentAuthor < ActiveRecord::Base

assert_not DestroyByParentBook.exists?(book.id)
end

class UndestroyableBook < ActiveRecord::Base
self.table_name = "books"
belongs_to :author, class_name: "DestroyableAuthor"
before_destroy :dont

def dont
throw(:abort)
end
end

class DestroyableAuthor < ActiveRecord::Base
self.table_name = "authors"
has_one :book, class_name: "UndestroyableBook", foreign_key: "author_id", dependent: :destroy
end

def test_dependency_should_halt_parent_destruction
author = DestroyableAuthor.create!(name: "Test")
UndestroyableBook.create!(author: author)

assert_no_difference ["DestroyableAuthor.count", "UndestroyableBook.count"] do
assert_not author.destroy
end
end
end

0 comments on commit b0fc04a

Please sign in to comment.