Find an ActiveRecord by any column (useful for Cucumber steps)

The attached patch lets you find a record by a string or number in any column:

User.find_by_anything('carla')
User.find_by_anything('email@domain.de')
User.find_by_anything(10023)

There's also a bang variant that raises ActiveRecord::NotFound if no record matches the given value:

User.find_by_anything!('carla')

Boolean and binary columns are excluded from the search because that would be crazy.

I recommend copying the attachment to features/support/find_by_anything.rb, since it is most useful in Cucumber step definitions (see below).

Application in Cucumber step definitions

You should use this in step definitions that look up a record by some identifier. This makes your step much more flexible, since now you won't have to go out of your way to create scenarios where e.g. users have known screen names, e-mail addresses, full names, etc., only because your step definition requires that.

Here's a typical step definitions that benefits from using find_by_anything:

When /^I sign in as "([^\"]+)")$/ do |identifier|
  user = User.find_by_anything!(identifier)
  visit new_session_path
  fill_in 'E-mail', :with => user.email
  fill_in 'Password', :with => "secret"
  click_button 'Sign in'
end

You can now use any of the following steps:

When I sign in as "carla@domain.de"
When I sign in as "Carla"
When I sign in as "carcar79"

Patch to make it work for Rails 2

For Rails 2, the last line of find_by_anything needs to be changed to:

find(:first, :conditions => [query_clauses.join(' OR '), *bindings])
Henning Koch About 12 years ago