diff options
3 files changed, 17 insertions, 50 deletions
diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index 1c3a6b56f3..f4e34657a5 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -418,15 +418,10 @@ module ActiveRecord end def method_missing(method, *args) - case method.to_s - when 'find_or_create' - return find(:first, :conditions => args.first) || create(args.first) - when /^find_or_create_by_(.*)$/ - rest = $1 - return send("find_by_#{rest}", *args) || - method_missing("create_by_#{rest}", *args) - when /^create_by_(.*)$/ - return create Hash[$1.split('_and_').zip(args)] + 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)]) end if @target.respond_to?(method) || (!@reflection.klass.respond_to?(method) && Class.respond_to?(method)) diff --git a/activerecord/lib/active_record/dynamic_finder_match.rb b/activerecord/lib/active_record/dynamic_finder_match.rb index b39b291352..dfb8a3ba60 100644 --- a/activerecord/lib/active_record/dynamic_finder_match.rb +++ b/activerecord/lib/active_record/dynamic_finder_match.rb @@ -42,6 +42,10 @@ module ActiveRecord @finder == :first && !@instantiator.nil? end + def creator? + @finder == :first && @instantiator == :create + end + def bang? @bang end diff --git a/activerecord/test/cases/associations/has_many_associations_test.rb b/activerecord/test/cases/associations/has_many_associations_test.rb index 6218cdd344..6fe737a817 100644 --- a/activerecord/test/cases/associations/has_many_associations_test.rb +++ b/activerecord/test/cases/associations/has_many_associations_test.rb @@ -47,14 +47,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase Client.destroyed_client_ids.clear end - def test_create_by - person = Person.create! :first_name => 'tenderlove' - post = Post.find :first + def test_create_resets_cached_counters + person = Person.create!(:first_name => 'tenderlove') + post = Post.first assert_equal [], person.readers - assert_nil person.readers.find_by_post_id post.id + assert_nil person.readers.find_by_post_id(post.id) - reader = person.readers.create_by_post_id post.id + reader = person.readers.create(:post_id => post.id) assert_equal 1, person.readers.count assert_equal 1, person.readers.length @@ -62,13 +62,14 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal person, person.readers.first.person end - def test_create_by_multi + def test_find_or_create_by_resets_cached_counters person = Person.create! :first_name => 'tenderlove' - post = Post.find :first + post = Post.first assert_equal [], person.readers + assert_nil person.readers.find_by_post_id(post.id) - reader = person.readers.create_by_post_id_and_skimmer post.id, false + reader = person.readers.find_or_create_by_post_id(post.id) assert_equal 1, person.readers.count assert_equal 1, person.readers.length @@ -76,39 +77,6 @@ class HasManyAssociationsTest < ActiveRecord::TestCase assert_equal person, person.readers.first.person end - def test_find_or_create_by - person = Person.create! :first_name => 'tenderlove' - post = Post.find :first - - assert_equal [], person.readers - assert_nil person.readers.find_by_post_id post.id - - reader = person.readers.find_or_create_by_post_id post.id - - assert_equal 1, person.readers.count - assert_equal 1, person.readers.length - assert_equal post, person.readers.first.post - assert_equal person, person.readers.first.person - end - - def test_find_or_create - person = Person.create! :first_name => 'tenderlove' - post = Post.find :first - - assert_equal [], person.readers - assert_nil person.readers.find(:first, :conditions => { - :post_id => post.id - }) - - reader = person.readers.find_or_create :post_id => post.id - - assert_equal 1, person.readers.count - assert_equal 1, person.readers.length - assert_equal post, person.readers.first.post - assert_equal person, person.readers.first.person - end - - def force_signal37_to_load_all_clients_of_firm companies(:first_firm).clients_of_firm.each {|f| } end |