Skip to content
This repository
Browse code

Fixing dynamic finders on associations to properly send arguments to …

…the find_by_* method. Closes issue #330.

Commit fdfc8e3 introduced a bugfix to prevent additional values passed
to a dynamic find_or_create_by_x methods from confusing the finder.
This patch also broke the essential behavior of this method on an
association by incorrectly sending arguments to the find_by_x methods.
The finder method would always see its inputs as a single array of
values instead of individual arguments, almost guaranteeing that the
finder call would be incorrect, and that we'd always create a new
record instead.

This patch adds a splat operator to the parameter array we send along to
the dynamic finder so that it receives its inputs correctly, and
includes an additional test to ensure that repeated calls to
find_or_create_by_x only creates one new record.
  • Loading branch information...
commit 9f7ff621bd62ade37b4ae4e608bdf24b7f7b1456 1 parent b0be721
Casey Dreier authored
2  activerecord/lib/active_record/associations/association_collection.rb
@@ -381,7 +381,7 @@ def method_missing(method, *args, &block)
381 381
           when /^find_or_create_by_(.*)$/
382 382
             rest = $1
383 383
             find_args = pull_finder_args_from(DynamicFinderMatch.match(method).attribute_names, *args)
384  
-            return  send("find_by_#{rest}", find_args) ||
  384
+            return  send("find_by_#{rest}", *find_args) ||
385 385
                     method_missing("create_by_#{rest}", *args, &block)
386 386
           when /^create_by_(.*)$/
387 387
             return create($1.split('_and_').zip(args).inject({}) { |h,kv| k,v=kv ; h[k] = v ; h }, &block)
9  activerecord/test/cases/associations/has_many_associations_test.rb
@@ -82,6 +82,15 @@ def test_find_or_create_by_with_additional_parameters
82 82
     assert_equal 4, post.comments.length
83 83
   end
84 84
 
  85
+  def test_find_or_create_by_with_same_parameters_creates_a_single_record
  86
+    author = Author.first
  87
+    assert_difference "Post.count", +1 do
  88
+      2.times do
  89
+        author.posts.find_or_create_by_body_and_title('one', 'two')
  90
+      end
  91
+    end
  92
+  end
  93
+
85 94
   def test_find_or_create_by_with_block
86 95
     post = Post.create! :title => 'test_find_or_create_by_with_additional_parameters', :body => 'this is the body'
87 96
     comment = post.comments.find_or_create_by_body('other test comment body') { |comment| comment.type = 'test' }

0 notes on commit 9f7ff62

Please sign in to comment.
Something went wrong with that request. Please try again.