aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/dynamic_finder_match.rb
diff options
context:
space:
mode:
authorPaul McMahon <paul@mobalean.com>2012-01-29 13:27:47 +0900
committerPaul McMahon <paul@mobalean.com>2012-01-29 13:27:47 +0900
commit2352b50e71d3165128317c7927eb0163d87ba992 (patch)
tree48e1584595e3e5a207a9a195f27c5e5f49c38b3d /activerecord/lib/active_record/dynamic_finder_match.rb
parentfe12497e4d8ad292ffbcb4486a26b8802c19d65d (diff)
downloadrails-2352b50e71d3165128317c7927eb0163d87ba992.tar.gz
rails-2352b50e71d3165128317c7927eb0163d87ba992.tar.bz2
rails-2352b50e71d3165128317c7927eb0163d87ba992.zip
Decouple finding matching class from instantiation
Diffstat (limited to 'activerecord/lib/active_record/dynamic_finder_match.rb')
-rw-r--r--activerecord/lib/active_record/dynamic_finder_match.rb51
1 files changed, 29 insertions, 22 deletions
diff --git a/activerecord/lib/active_record/dynamic_finder_match.rb b/activerecord/lib/active_record/dynamic_finder_match.rb
index 2b4f1bbf92..638b68bc52 100644
--- a/activerecord/lib/active_record/dynamic_finder_match.rb
+++ b/activerecord/lib/active_record/dynamic_finder_match.rb
@@ -6,17 +6,23 @@ module ActiveRecord
#
class DynamicFinderMatch
def self.match(method)
- [ FindBy, FindByBang, FindOrInitializeCreateBy ].each do |klass|
- o = klass.match(method.to_s)
- return o if o
+ method = method.to_s
+ klass = [FindBy, FindByBang, FindOrInitializeCreateBy].find do |klass|
+ klass.matches?(method)
end
- nil
+ klass.try(:new, method)
end
- def initialize(finder, names, instantiator = nil)
- @finder = finder
- @instantiator = instantiator
- @attribute_names = names.split('_and_')
+ def self.matches?(method)
+ method =~ self::METHOD_PATTERN
+ end
+
+ def initialize(method)
+ @finder = :first
+ @instantiator = nil
+ match_data = method.match(self.class::METHOD_PATTERN)
+ @attribute_names = match_data[-1].split("_and_")
+ initialize_from_match_data(match_data)
end
attr_reader :finder, :attribute_names, :instantiator
@@ -40,22 +46,24 @@ module ActiveRecord
def valid_arguments?(arguments)
arguments.size >= @attribute_names.size
end
+
+ private
+
+ def initialize_from_match_data(match_data)
+ end
end
class FindBy < DynamicFinderMatch
- def self.match(method)
- if method =~ /^find_(all_|last_)?by_([_a-zA-Z]\w*)$/
- new($1 == 'last_' ? :last : $1 == 'all_' ? :all : :first, $2)
- end
+ METHOD_PATTERN = /^find_(all_|last_)?by_([_a-zA-Z]\w*)$/
+
+ def initialize_from_match_data(match_data)
+ @finder = :last if match_data[1] == 'last_'
+ @finder = :all if match_data[1] == 'all_'
end
end
class FindByBang < DynamicFinderMatch
- def self.match(method)
- if method =~ /^find_by_([_a-zA-Z]\w*)\!$/
- new(:first, $1)
- end
- end
+ METHOD_PATTERN = /^find_by_([_a-zA-Z]\w*)\!$/
def bang?
true
@@ -63,11 +71,10 @@ module ActiveRecord
end
class FindOrInitializeCreateBy < DynamicFinderMatch
- def self.match(method)
- instantiator = nil
- if method =~ /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/
- new(:first, $2, $1 == 'initialize' ? :new : :create)
- end
+ METHOD_PATTERN = /^find_or_(initialize|create)_by_([_a-zA-Z]\w*)$/
+
+ def initialize_from_match_data(match_data)
+ @instantiator = match_data[1] == 'initialize' ? :new : :create
end
def valid_arguments?(arguments)