diff options
author | Ben Woosley <ben.woosley@gmail.com> | 2013-06-18 15:10:48 -0700 |
---|---|---|
committer | Ben Woosley <pair+ben@pacerpro.com> | 2014-10-03 03:04:16 -0700 |
commit | cc405496ce85ee0073268baefdb2be5d4b062f91 (patch) | |
tree | 9a7721c2b03e95b01faacafe89782c1fea5c9d45 /activerecord/lib | |
parent | de50a91daad90bf2a0e6bece60a1c2211ade4682 (diff) | |
download | rails-cc405496ce85ee0073268baefdb2be5d4b062f91.tar.gz rails-cc405496ce85ee0073268baefdb2be5d4b062f91.tar.bz2 rails-cc405496ce85ee0073268baefdb2be5d4b062f91.zip |
Fix that a collection proxy could be cached before the save of the owner, resulting in an invalid proxy lacking the owner’s id.
Absent this fix calls like: owner.association.update_all to behave unexpectedly because they try to act on association objects where
owner_id is null.
more evidence here: https://gist.github.com/Empact/5865555
```
Active Record 3.2.13
-- create_table(:firms, {:force=>true})
-> 0.1371s
-- create_table(:clients, {:force=>true})
-> 0.0005s
1 clients. 1 expected.
1 clients updated. 1 expected.
```
```
Active Record 4.0.0
-- create_table(:firms, {:force=>true})
-> 0.1606s
-- create_table(:clients, {:force=>true})
-> 0.0004s
1 clients. 1 expected.
0 clients updated. 1 expected.
```
Diffstat (limited to 'activerecord/lib')
-rw-r--r-- | activerecord/lib/active_record/associations/collection_association.rb | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/associations/collection_association.rb b/activerecord/lib/active_record/associations/collection_association.rb index 1836ff0910..c5dff7ee1a 100644 --- a/activerecord/lib/active_record/associations/collection_association.rb +++ b/activerecord/lib/active_record/associations/collection_association.rb @@ -33,7 +33,13 @@ module ActiveRecord reload end - @proxy ||= CollectionProxy.create(klass, self) + if owner.new_record? + # Cache the proxy separately before the owner has an id + # or else a post-save proxy will still lack the id + @new_record_proxy ||= CollectionProxy.create(klass, self) + else + @proxy ||= CollectionProxy.create(klass, self) + end end # Implements the writer method, e.g. foo.items= for Foo.has_many :items |