Permalink
Browse files

Updated ActiveRecord::Base.find_or_create_by for 2 attributes when 1 …

…is nil

Updated the find_or_create_by_foo_and_bar('hello') to process the find portion
similar to find_by_foo_and_bar('hello').  In the original
find_by_foo_and_bar('hello'), the resulting query was something like
"foo = 'hello' AND bar IS NULL".  In the original
find_or_create_by_foo_and_bar('hello'), the resulting query was something like
"foo = 'hello'"

This patch aligns those two methods expected behaviors on the "find" portion
of the method call.
  • Loading branch information...
1 parent ae323a5 commit 4c67e39861d2efb8e750b96f159c3c14cd8ece22 @jeremyf committed May 24, 2011
@@ -273,8 +273,13 @@ def find_or_instantiator_by_attributes(match, attributes, *args)
unprotected_attributes_for_create[attributes[i]] = args[i]
end
end
+ attributes_for_create = protected_attributes_for_create.merge(unprotected_attributes_for_create)
- conditions = (protected_attributes_for_create.merge(unprotected_attributes_for_create)).slice(*attributes).symbolize_keys
+ if attributes_for_create.length < attributes.length
+ attributes.each { |attrib| attributes_for_create[attrib] ||= nil }
+ end
+
+ conditions = (attributes_for_create).slice(*attributes).symbolize_keys
record = where(conditions).first
@@ -815,6 +815,18 @@ def test_find_or_create_from_two_attributes_with_one_being_an_aggregate
assert created_customer.persisted?
end
+ def test_find_or_create_from_two_attributes_with_one_not_included
+ assert Author.find_by_name('David')
+ assert_no_difference 'Author.count' do
+ Author.find_or_create_by_name('David')
+ end
+
+ assert_nil Author.find_by_name_and_author_address_id('David')
+ assert_difference 'Author.count' do
+ Author.find_or_create_by_name_and_author_address_id('David')
+ end
+ end
+
def test_find_or_create_from_one_attribute_and_hash
number_of_companies = Company.count
sig38 = Company.find_or_create_by_name({:name => "38signals", :firm_id => 17, :client_of => 23})

0 comments on commit 4c67e39

Please sign in to comment.