diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 8acb585f91ed6..77bfec6e10b8a 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -375,7 +375,7 @@ def load_target target end - def method_missing(method, *args) + def method_missing(method, *args, &block) case method.to_s when 'find_or_create' return find(:first, :conditions => args.first) || create(args.first) @@ -383,9 +383,9 @@ def method_missing(method, *args) rest = $1 find_args = pull_finder_args_from(DynamicFinderMatch.match(method).attribute_names, *args) return send("find_by_#{rest}", find_args) || - method_missing("create_by_#{rest}", *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 }) + return create($1.split('_and_').zip(args).inject({}) { |h,kv| k,v=kv ; h[k] = v ; h }, &block) end if @target.respond_to?(method) || (!@reflection.klass.respond_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 0b1b579ff4a19..47b0f1e88d9ee 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -82,6 +82,12 @@ def test_find_or_create_by_with_additional_parameters assert_equal 4, post.comments.length 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' } + assert_equal 'test', comment.type + end + def test_find_or_create person = Person.create! :first_name => 'tenderlove' post = Post.find :first