mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Prevent has_one from touching parent record unless persisted
Previously, if `build_association` was called multiple times for a `has_one` association but never committed to the database, the first newly-associated record would trigger `touch` during the attempted removal of the record. For example: class Post < ActiveRecord::Base has_one :comment, inverse_of: :post, dependent: :destroy end class Comment < ActiveRecord::Base belongs_to :post, inverse_of: :comment, touch: true end post = Post.create! comment_1 = post.build_comment comment_2 = post.build_comment When `comment_2` is initialized, the `has_one` would attempt to destroy `comment_1`, triggering a `touch` on `post` from an association record that hasn't been committed to the database. This removes the attempt to delete an associated `has_one` unless it’s persisted.
This commit is contained in:
parent
a4deb63798
commit
ba3ef762fc
3 changed files with 27 additions and 1 deletions
|
@ -1,3 +1,9 @@
|
|||
* Prevent `build_association` from `touching` a parent record if the record isn't persisted for `has_one` associations.
|
||||
|
||||
Fixes #38219
|
||||
|
||||
*Josh Brody*
|
||||
|
||||
* Add support for `if_not_exists` option for adding index.
|
||||
|
||||
The `add_index` method respects `if_not_exists` option. If it is set to true
|
||||
|
|
|
@ -81,7 +81,9 @@ module ActiveRecord
|
|||
target.delete
|
||||
when :destroy
|
||||
target.destroyed_by_association = reflection
|
||||
target.destroy
|
||||
if target.persisted?
|
||||
target.destroy
|
||||
end
|
||||
else
|
||||
nullify_owner_attributes(target)
|
||||
remove_inverse_instance(target)
|
||||
|
|
|
@ -851,4 +851,22 @@ class HasOneAssociationsTest < ActiveRecord::TestCase
|
|||
assert_not author.destroy
|
||||
end
|
||||
end
|
||||
|
||||
class SpecialCar < ActiveRecord::Base
|
||||
self.table_name = "cars"
|
||||
has_one :special_bulb, inverse_of: :car, dependent: :destroy, class_name: "SpecialBulb", foreign_key: "car_id"
|
||||
end
|
||||
|
||||
class SpecialBulb < ActiveRecord::Base
|
||||
self.table_name = "bulbs"
|
||||
belongs_to :car, inverse_of: :special_bulb, touch: true, class_name: "SpecialCar"
|
||||
end
|
||||
|
||||
def test_has_one_with_touch_option_on_nonpersisted_built_associations_doesnt_update_parent
|
||||
car = SpecialCar.create(name: "honda")
|
||||
assert_queries(1) do
|
||||
car.build_special_bulb
|
||||
car.build_special_bulb
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue