From eee32af45e7909c02370324833d7117fe9b6eb37 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Mon, 12 Mar 2012 11:39:19 +0000 Subject: Add dynamic find_or_create_by_{attribute}! method. --- .../lib/active_record/dynamic_finder_match.rb | 26 +++++++++++++++++++++- .../lib/active_record/relation/finder_methods.rb | 2 +- 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'activerecord/lib/active_record') diff --git a/activerecord/lib/active_record/dynamic_finder_match.rb b/activerecord/lib/active_record/dynamic_finder_match.rb index 38dbbef5fc..0473d6aafc 100644 --- a/activerecord/lib/active_record/dynamic_finder_match.rb +++ b/activerecord/lib/active_record/dynamic_finder_match.rb @@ -7,7 +7,7 @@ module ActiveRecord class DynamicFinderMatch def self.match(method) method = method.to_s - klass = [FindBy, FindByBang, FindOrInitializeCreateBy].find do |_klass| + klass = klasses.find do |_klass| _klass.matches?(method) end klass.new(method) if klass @@ -17,6 +17,10 @@ module ActiveRecord method =~ self::METHOD_PATTERN end + def self.klasses + [FindBy, FindByBang, FindOrInitializeCreateBy, FindOrCreateByBang] + end + def initialize(method) @finder = :first @instantiator = nil @@ -47,6 +51,14 @@ module ActiveRecord arguments.size >= @attribute_names.size end + def save_record? + @instantiator == :create + end + + def save_method + bang? ? :save! : :save + end + private def initialize_from_match_data(match_data) @@ -81,4 +93,16 @@ module ActiveRecord arguments.size == 1 && arguments.first.is_a?(Hash) || super end end + + class FindOrCreateByBang < DynamicFinderMatch + METHOD_PATTERN = /^find_or_create_by_([_a-zA-Z]\w*)\!$/ + + def initialize_from_match_data(match_data) + @instantiator = :create + end + + def bang? + true + end + end end diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb index 4cd703e0a5..adfacf37ee 100644 --- a/activerecord/lib/active_record/relation/finder_methods.rb +++ b/activerecord/lib/active_record/relation/finder_methods.rb @@ -290,7 +290,7 @@ module ActiveRecord r.assign_attributes(unprotected_attributes_for_create, :without_protection => true) end yield(record) if block_given? - record.save if match.instantiator == :create + record.send(match.save_method) if match.save_record? end record -- cgit v1.2.3