From 748d09f777795209fb2f4619d67d07d017647a46 Mon Sep 17 00:00:00 2001 From: Phil Smith Date: Mon, 12 Jul 2010 09:14:57 -0700 Subject: [PATCH] DynamicFinderMatch will match find_or_(initialize|create) without a trailing _by_attribute_list [#5097 state:resolved] --- activerecord/lib/active_record/base.rb | 8 ++++++++ .../lib/active_record/dynamic_finder_match.rb | 4 ++-- activerecord/test/cases/finder_test.rb | 20 ++++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index c78060c..9a14fb3 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -191,6 +191,14 @@ module ActiveRecord #:nodoc: # winter = Tag.find_or_initialize_by_name("Winter") # winter.new_record? # true # + # It is also possible to call these finders without additional attributes, in case the relevant conditions have already been built up in a relation or named scope. For example: + # + # # The customer has no open tab + # customer.tabs.find_or_create # equal to Tab.create(:customer => customer) + # + # # Now a tab does exist + # customer.tabs.find_or_create # equal to customer.tabs.first + # # To find by a subset of the attributes to be used for instantiating a new object, pass a hash instead of # a list of parameters. For example: # diff --git a/activerecord/lib/active_record/dynamic_finder_match.rb b/activerecord/lib/active_record/dynamic_finder_match.rb index b39b291..7868855 100644 --- a/activerecord/lib/active_record/dynamic_finder_match.rb +++ b/activerecord/lib/active_record/dynamic_finder_match.rb @@ -23,9 +23,9 @@ module ActiveRecord when /^find_by_([_a-zA-Z]\w*)\!$/ @bang = true names = $1 - when /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/ + when /^find_or_(initialize|create)(_by_([_a-zA-Z]\w*))?$/ @instantiator = $1 == 'initialize' ? :new : :create - names = $2 + names = $3 || '' else @finder = nil end diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb index 860d330..0eb0079 100644 --- a/activerecord/test/cases/finder_test.rb +++ b/activerecord/test/cases/finder_test.rb @@ -61,6 +61,26 @@ class DynamicFinderMatchTest < ActiveRecord::TestCase assert_equal :create, match.instantiator assert_equal %w(age sex location), match.attribute_names end + + def test_find_or_initialize + match = ActiveRecord::DynamicFinderMatch.match("find_or_initialize") + assert_not_nil match + assert !match.finder? + assert match.instantiator? + assert_equal :first, match.finder + assert_equal :new, match.instantiator + assert_equal [], match.attribute_names + end + + def test_find_or_create + match = ActiveRecord::DynamicFinderMatch.match("find_or_create") + assert_not_nil match + assert !match.finder? + assert match.instantiator? + assert_equal :first, match.finder + assert_equal :create, match.instantiator + assert_equal [], match.attribute_names + end end class FinderTest < ActiveRecord::TestCase -- 1.6.6