Skip to content

Commit e09da8b

Browse files
committed
Reload through_record that has been destroyed in create_through_record
This is an alternative of #27714. If `has_one :through` association has set `nil`, `through_record` is destroyed but still remain loaded target in `through_proxy` until `reload` or `reset` explicitly. If `through_proxy` is not reset (remain destroyed (frozen) target), setting new record causes `RuntimeError: Can't modify frozen hash`. To prevent `RuntimeError`, should reload `through_record` that has been destroyed in `create_through_record`.
1 parent 6a1c021 commit e09da8b

File tree

2 files changed

+11
-0
lines changed

2 files changed

+11
-0
lines changed

activerecord/lib/active_record/associations/has_one_through_association.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ def create_through_record(record)
2222
elsif record
2323
attributes = construct_join_attributes(record)
2424

25+
if through_record && through_record.destroyed?
26+
through_record = through_proxy.tap(&:reload).target
27+
end
28+
2529
if through_record
2630
through_record.update(attributes)
2731
elsif owner.new_record?

activerecord/test/cases/associations/has_one_through_associations_test.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ def test_set_record_to_nil_should_delete_association
8686
assert_nil @member.club
8787
end
8888

89+
def test_set_record_after_delete_association
90+
@member.club = nil
91+
@member.club = clubs(:moustache_club)
92+
@member.reload
93+
assert_equal clubs(:moustache_club), @member.club
94+
end
95+
8996
def test_has_one_through_polymorphic
9097
assert_equal clubs(:moustache_club), @member.sponsor_club
9198
end

0 commit comments

Comments
 (0)