New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix + Failing test for find_or_initialize_ updating has_many collection size. #3610
Conversation
When a record is initialized through a has_many association, the record is added to the target association. On a record.save, this record is not updated or replaced in the in-memory association. e.g. @tree.apples.size #=> 1 apple = @tree.apples.find_or_initialize_by_color('Red') @tree.apples.size #=> 2, so it added a record in-memory. apple.color = 'Green' apple.save @tree.apples.size #=> 3 !!! It did reload records from database. It did not clear in-memory records. @tree.apples.last.color #=> 'Red' @tree.apples.last.new_record? #=> true @tree.apples.second.color #=> 'Green' @tree.apples.second.new_record? #=> false
What I don't get is that it only happens when using |
The problem is not in the Or it doing |
…lly returns the result of the finder. Current implementation does not stop execution and actually calls the finder twice. Fix #3610
Maybe the implications aren't totally clear. For example, if you use |
bump. We hit this problem when we migrated from Rails 3.0 to Rails 3.1. |
Are you sure this affects find_or_create? If so, any idea why this bug is not showing up in the existing activerecord test suite? I wouldn't expect that there would necessarily test for the number of queries run or objects initialized, but there are has_many tests that check that find_or_create only creates once, for example: def test_dynamic_find_or_create_from_two_attributes_using_an_association
author = authors(:david)
number_of_posts = Post.count
another = author.posts.find_or_create_by_title_and_body("Another Post", "This is the Body")
assert_equal number_of_posts + 1, Post.count
assert_equal another, author.posts.find_or_create_by_title_and_body("Another Post", "This is the Body")
assert another.persisted?
end Which is passing on the 3-1-stable branch. For what it's worth, there is also a check on #size after using find_or_initialize, though it could well be doing the find twice: def test_find_or_initialize_updates_collection_size
number_of_clients = companies(:first_firm).clients_of_firm.size
companies(:first_firm).clients_of_firm.find_or_initialize_by_name("name" => "Another Client")
assert_equal number_of_clients + 1, companies(:first_firm).clients_of_firm.size
end If you could create a failing test case for the problem I think that would help get this patch merged a lot. |
…lly returns the result of the finder. Current implementation does not stop execution and actually calls the finder twice. Fix rails#3610
@mlangenberg I think this has already changed on 3-2/master, if you confirm that please close this issue. Thanks. |
Confirmed it is fixed as of Rails 3.2.2. Thanks! |
It's fixed in 3.2 indeed. Thanks all. |
When a record is initialized through a has_many association, the record is added to the target association.
On a record.save, this record is not updated or replaced in the in-memory association.
e.g.