Created
December 16, 2010 02:01
-
-
Save openfirmware/742909 to your computer and use it in GitHub Desktop.
[PATCH] Fix find_or_create_by_x on association bug [#6147 state:resolved]
This file contains 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 12c8326e8c6c1f21a6b56f4d0a5fcdb932d0fa56 Mon Sep 17 00:00:00 2001 | |
From: James Badger <[email protected]> | |
Date: Wed, 15 Dec 2010 15:55:51 -0700 | |
Subject: [PATCH] Fix find_or_create_by_x on association bug [#6147 state:resolved] | |
Commit fdfc8e3b9c4905057677fd009f463a377be60b93 fixed the | |
find_or_create_by_x find() being confused by the extra parameters, | |
but the create_by_x code from b64d1fe637d16916c59e2ddec403d9c7cd54b0f8 | |
does not convert the array properly for create(). This patch allows | |
sending of params with additional hash attributes by changing the | |
array conversion method. | |
--- | |
.../associations/association_collection.rb | 4 ++- | |
.../associations/has_many_associations_test.rb | 32 ++++++++++++++++++++ | |
2 files changed, 35 insertions(+), 1 deletions(-) | |
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb | |
index 3a602e4..3490980 100644 | |
--- a/activerecord/lib/active_record/associations/association_collection.rb | |
+++ b/activerecord/lib/active_record/associations/association_collection.rb | |
@@ -384,7 +384,9 @@ module ActiveRecord | |
return send("find_by_#{rest}", find_args) || | |
method_missing("create_by_#{rest}", *args, &block) | |
when /^create_by_(.*)$/ | |
- return create($1.split('_and_').zip(args).inject({}) { |h,kv| k,v=kv ; h[k] = v ; h }, &block) | |
+ hash = $1.split('_and_').zip(args).inject({}) { |h,kv| k,v=kv ; h[k.to_sym] = v ; h } | |
+ hash.merge!(args.inject({}) { |h,v| v.is_a?(Hash) ? h.merge(v) : h }) | |
+ return create(hash, &block) | |
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 3996b84..062929f 100644 | |
--- a/activerecord/test/cases/associations/has_many_associations_test.rb | |
+++ b/activerecord/test/cases/associations/has_many_associations_test.rb | |
@@ -82,6 +82,38 @@ class HasManyAssociationsTest < ActiveRecord::TestCase | |
assert_equal 4, post.comments.length | |
end | |
+ def test_find_or_create_by_with_hash_sets_proper_attributes | |
+ author = Author.create!(:name => "Sir Vayor") | |
+ post = author.posts.create!(:title => "A fine post", :body => "It is fine, is it not?") | |
+ assert_equal 1, author.posts.count | |
+ assert_equal 1, author.posts.length | |
+ assert_equal post, author.posts.find_or_create_by_title("A fine post") | |
+ | |
+ post = author.posts.find_or_create_by_title(:title => "A wood post", :body => "It is made of wood.") | |
+ assert_equal 2, author.posts.count | |
+ assert_equal 2, author.posts.length | |
+ assert_equal "A wood post", post.title | |
+ assert_equal "It is made of wood.", post.body | |
+ | |
+ post = author.posts.find_or_create_by_title("An iron post", :body => "A heavy post made of iron.") | |
+ assert_equal 3, author.posts.count | |
+ assert_equal 3, author.posts.length | |
+ assert_equal "An iron post", post.title | |
+ assert_equal "A heavy post made of iron.", post.body | |
+ | |
+ post = author.posts.find_or_create_by_title_and_body("A witness post", "The other post was near here.") | |
+ assert_equal 4, author.posts.count | |
+ assert_equal 4, author.posts.length | |
+ assert_equal "A witness post", post.title | |
+ assert_equal "The other post was near here.", post.body | |
+ | |
+ post = author.posts.find_or_create_by_title_and_body("The last post", "If only they were this easy to find.", {:title => "Maybe not the last post", :body => "Another post."}) | |
+ assert_equal 5, author.posts.count | |
+ assert_equal 5, author.posts.length | |
+ assert_equal "Maybe not the last post", post.title | |
+ assert_equal "Another post.", post.body | |
+ end | |
+ | |
def test_find_or_create_by_with_block | |
post = Post.create! :title => 'test_find_or_create_by_with_additional_parameters', :body => 'this is the body' | |
comment = post.comments.find_or_create_by_body('other test comment body') { |comment| comment.type = 'test' } | |
-- | |
1.7.0.4 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment