Skip to content
Browse files

Make Model.find_or_create_by_* and find_or_initialize_by_* use relati…

…ons and remove method caching
  • Loading branch information...
1 parent d511de0 commit 85770ec7139fcba985310d239d4c57cfe6f6c60b @lifo lifo committed Dec 27, 2009
View
55 activerecord/lib/active_record/base.rb
@@ -1864,60 +1864,7 @@ def method_missing(method_id, *arguments, &block)
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
View
7 activerecord/lib/active_record/relation.rb
@@ -164,11 +164,12 @@ def find_by_attributes(match, attributes, *args)
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
View
7 activerecord/test/cases/finder_test.rb
@@ -880,13 +880,6 @@ class << Company
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

0 comments on commit 85770ec

Please sign in to comment.
Something went wrong with that request. Please try again.