aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2009-12-27 14:46:38 +0530
committerPratik Naik <pratiknaik@gmail.com>2009-12-27 14:46:38 +0530
commit85770ec7139fcba985310d239d4c57cfe6f6c60b (patch)
tree6ac06f74e46385f86ef51feb55e69730f1ca1020 /activerecord
parentd511de0261003aae4913e3c24f76df6e03a35916 (diff)
downloadrails-85770ec7139fcba985310d239d4c57cfe6f6c60b.tar.gz
rails-85770ec7139fcba985310d239d4c57cfe6f6c60b.tar.bz2
rails-85770ec7139fcba985310d239d4c57cfe6f6c60b.zip
Make Model.find_or_create_by_* and find_or_initialize_by_* use relations and remove method caching
Diffstat (limited to 'activerecord')
-rwxr-xr-xactiverecord/lib/active_record/base.rb55
-rw-r--r--activerecord/lib/active_record/relation.rb7
-rw-r--r--activerecord/test/cases/finder_test.rb7
3 files changed, 5 insertions, 64 deletions
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 31737043eb..cba1e0ebe6 100755
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -1864,60 +1864,7 @@ module ActiveRecord #:nodoc:
relation = options.any? ? construct_finder_arel_with_includes(options) : scoped
relation.send :find_by_attributes, match, attribute_names, *arguments
elsif match.instantiator?
- instantiator = match.instantiator
- # def self.find_or_create_by_user_id(*args)
- # guard_protected_attributes = false
- #
- # if args[0].is_a?(Hash)
- # guard_protected_attributes = true
- # attributes = args[0].with_indifferent_access
- # find_attributes = attributes.slice(*[:user_id])
- # else
- # find_attributes = attributes = construct_attributes_from_arguments([:user_id], args)
- # end
- #
- # options = { :conditions => find_attributes }
- # set_readonly_option!(options)
- #
- # record = find(:first, options)
- #
- # if record.nil?
- # record = self.new { |r| r.send(:attributes=, attributes, guard_protected_attributes) }
- # yield(record) if block_given?
- # record.save
- # record
- # else
- # record
- # end
- # end
- self.class_eval %{
- def self.#{method_id}(*args)
- guard_protected_attributes = false
-
- if args[0].is_a?(Hash)
- guard_protected_attributes = true
- attributes = args[0].with_indifferent_access
- find_attributes = attributes.slice(*[:#{attribute_names.join(',:')}])
- else
- find_attributes = attributes = construct_attributes_from_arguments([:#{attribute_names.join(',:')}], args)
- end
-
- options = { :conditions => find_attributes }
- set_readonly_option!(options)
-
- record = find(:first, options)
-
- if record.nil?
- record = self.new { |r| r.send(:attributes=, attributes, guard_protected_attributes) }
- #{'yield(record) if block_given?'}
- #{'record.save' if instantiator == :create}
- record
- else
- record
- end
- end
- }, __FILE__, __LINE__
- send(method_id, *arguments, &block)
+ scoped.send :find_or_instantiator_by_attributes, match, attribute_names, *arguments, &block
end
elsif match = DynamicScopeMatch.match(method_id)
attribute_names = match.attribute_names
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index f17b889c53..89b9b9b4ff 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -164,11 +164,12 @@ module ActiveRecord
def find_or_instantiator_by_attributes(match, attributes, *args)
guard_protected_attributes = false
- attributes_for_create = conditions = attributes.inject({}) {|h, a| h[a] = args[attributes.index(a)]; h}
-
if args[0].is_a?(Hash)
guard_protected_attributes = true
- conditions = args[0].with_indifferent_access.slice(*attributes).symbolize_keys
+ attributes_for_create = args[0].with_indifferent_access
+ conditions = attributes_for_create.slice(*attributes).symbolize_keys
+ else
+ attributes_for_create = conditions = attributes.inject({}) {|h, a| h[a] = args[attributes.index(a)]; h}
end
record = where(conditions).first
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 59c016d19c..c531a2dec1 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -880,13 +880,6 @@ class FinderTest < ActiveRecord::TestCase
assert !c.new_record?
end
- def test_dynamic_find_or_initialize_from_one_attribute_caches_method
- class << Company; self; end.send(:remove_method, :find_or_initialize_by_name) if Company.public_methods.any? { |m| m.to_s == 'find_or_initialize_by_name' }
- assert !Company.public_methods.any? { |m| m.to_s == 'find_or_initialize_by_name' }
- sig38 = Company.find_or_initialize_by_name("38signals")
- assert Company.public_methods.any? { |m| m.to_s == 'find_or_initialize_by_name' }
- end
-
def test_find_or_initialize_from_two_attributes
another = Topic.find_or_initialize_by_title_and_author_name("Another topic","John")
assert_equal "Another topic", another.title