Created
May 14, 2011 02:35
-
-
Save AquaGeek/971849 to your computer and use it in GitHub Desktop.
Rails Lighthouse ticket #6741
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| From 86ea94e4d0c228c79b3709f0c667ba90b02e41cd Mon Sep 17 00:00:00 2001 | |
| From: Nick Howard <[email protected]> | |
| Date: Sun, 1 May 2011 16:22:46 -0600 | |
| Subject: [PATCH] Fix for lighthouse #6741 | |
| - adds tests for find_or_create_by and find_or_initialize_by on has_many associations | |
| - changes the behavior of ActiveRecord::Associations::CollectionProxy#method_missing to differ to | |
| ActiveRecord::FinderMethods#find_or_instantiator_by_attributes for arg processing and saving so | |
| find_or_create_by's api on associations will be consistent w/ the api for model classes. | |
| --- | |
| .../active_record/associations/collection_proxy.rb | 9 +++++-- | |
| .../associations/has_many_associations_test.rb | 24 ++++++++++++++++++++ | |
| 2 files changed, 30 insertions(+), 3 deletions(-) | |
| diff --git a/activerecord/lib/active_record/associations/collection_proxy.rb b/activerecord/lib/active_record/associations/collection_proxy.rb | |
| index 388173c..adfc71d 100644 | |
| --- a/activerecord/lib/active_record/associations/collection_proxy.rb | |
| +++ b/activerecord/lib/active_record/associations/collection_proxy.rb | |
| @@ -64,9 +64,12 @@ module ActiveRecord | |
| def method_missing(method, *args, &block) | |
| match = DynamicFinderMatch.match(method) | |
| - if match && match.creator? | |
| - attributes = match.attribute_names | |
| - return send(:"find_by_#{attributes.join('_and_')}", *args) || create(Hash[attributes.zip(args)]) | |
| + if match && match.instantiator? | |
| + record = send(:find_or_instantiator_by_attributes, match, match.attribute_names, *args) do |r| | |
| + @association.send :set_owner_attributes, r | |
| + @association.send :add_to_target, r | |
| + yield(r) if block_given? | |
| + end | |
| end | |
| if target.respond_to?(method) || ([email protected]_to?(method) && Class.respond_to?(method)) | |
| diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb | |
| index 007f11b..247decc 100644 | |
| --- a/activerecord/test/cases/associations/has_many_associations_test.rb | |
| +++ b/activerecord/test/cases/associations/has_many_associations_test.rb | |
| @@ -605,6 +605,30 @@ class HasManyAssociationsTest < ActiveRecord::TestCase | |
| assert_equal number_of_clients + 1, companies(:first_firm, :reload).clients.size | |
| end | |
| + 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 | |
| + | |
| + def test_find_or_create_with_hash | |
| + post = authors(:david).posts.find_or_create_by_title(:title => 'Yet another post', :body => 'somebody') | |
| + assert_equal post, authors(:david).posts.find_or_create_by_title(:title => 'Yet another post', :body => 'somebody') | |
| + assert post.persisted? | |
| + end | |
| + | |
| + def test_find_or_create_with_one_attribute_followed_by_hash | |
| + post = authors(:david).posts.find_or_create_by_title('Yet another post', :body => 'somebody') | |
| + assert_equal post, authors(:david).posts.find_or_create_by_title('Yet another post', :body => 'somebody') | |
| + assert post.persisted? | |
| + end | |
| + | |
| + def test_find_or_create_should_work_with_block | |
| + post = authors(:david).posts.find_or_create_by_title('Yet another post') {|p| p.body = 'somebody'} | |
| + assert_equal post, authors(:david).posts.find_or_create_by_title('Yet another post') {|p| p.body = 'somebody'} | |
| + assert post.persisted? | |
| + end | |
| + | |
| def test_deleting | |
| force_signal37_to_load_all_clients_of_firm | |
| companies(:first_firm).clients_of_firm.delete(companies(:first_firm).clients_of_firm.first) | |
| -- | |
| 1.7.0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment