ActiveRecord find_by_col1_and_col2 with hash parameters throws ArgumentError: wrong number of arguments (1 for 2) #5051

Closed
trisweb opened this Issue Feb 15, 2012 · 5 comments

Comments

Projects
None yet
3 participants
Contributor

trisweb commented Feb 15, 2012

When using find_by_col1_and_col2_... (more than one column) the argument count check in active_record/lib/dynamic_matchers.rb method_missing fails because it attempts to compare an array with the argument hash, to an array of straight argument names from the method call.

Example:

Calling, User.find_by_name_and_email(:name => "Tester", :email => "test@example.com") results in:

arguments = [{:name=>"Tester", :email=>"test@example.com"}]
attribute_names = ["name", "email"]

Such that the condition: if arguments.size < attribute_names.size always fails when attribute_names.size > 1

Workaround is to use new where syntax instead.

User.where(:name => "Tester", :email => "test@example.com")

Works great.

Initially discovered with User.find_or_create_by_, in which case the workaround is User.where(...).first_or_create(...), which also works fine.

Rails 3.2.1, Ruby 1.8.7

Owner

rafaelfranca commented Feb 15, 2012

Hey @trisweb!

Thanks for reporting.

The correct use of dynamics finders with more than one column is:

User.find_by_name_and_email("Tester", "test@example.com")

Internally the method missing will create a hash, like you described above, in these lines, as you can see in the comments.

Contributor

trisweb commented Feb 15, 2012

Thanks for the reply. So can I assume then that this format is officially unsupported?:

User.find_or_create_by_name_and_email(:name => "Tester", :email => "test@example.com", :city => "San Francisco", :etc => "Comments and more", ...)

Can't find that that shouldn't work in any of the docs, hence my confusion. (Also as far as I know, since this app was migrated from Rails 2, this did work previously).

Anyway it's a bit of a moot point since we've switched to the more correct User.where(...) form.

Owner

rafaelfranca commented Feb 15, 2012

Yeah. This format is officially unsupported. I'll try to update the docs to make this explicit.

Thanks

Contributor

trisweb commented Feb 15, 2012

Gotcha, thanks!

@trisweb trisweb closed this Feb 15, 2012

@trisweb About that unsupported version of find_or_create_by, the version that should work is:

User.find_or_create_by_name_and_email("Tester", "test@example.com", :city => "San Francisco", :etc => "Comments and more", ...)

Arguments for creation should be given as an extra argument.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment