For the longest time, I didn’t understand the full power of the various #find methods in Rails. I probably still don’t, but my understanding of them has certainly expanded. I used to use plain #find for everything. If I wanted to find all rows in the table ‘groups’ that had an ‘id’ field value of 1, 2, 3, or 4, I would do something like this:

1
2
3
4
Group.find(
  :all,
  :conditions => ["id=? OR id=? OR id=? OR ID=?", 1, 2, 3, 4]
)

Now, while this is a perfectly valid way to find those rows, it’s a little too verbose. There’s a cleaner, shorter way to get the same result:

1
Group.find([1, 2, 3, 4])

This works because #find can take any of the following as primary ID’s to look up:

  • a single ID:

    1
    
    Group.find(1)
    
  • an array of ID’s:

    1
    
    Group.find([1, 2, 3, 4])
    
  • an expanded array of ID’s:

    1
    
    Group.find(*[1, 2, 3, 4])
    
  • multiple ID’s:

    1
    
    Group.find(1, 2, 3, 4)
    

Beyond the regular #find method, there are also auto-generated methods for each of your Rails models. Say you have a UserGroup model that associates a user to a group, i.e. group membership. The table ‘users_groups’ has the fields ‘id’, ‘user_id’, and ‘group_id’. What’s an easy way to find all users belonging to the group with ID #3?

1
2
3
users = UserGroup.find_all_by_group_id(
  3, :include => :user, :order => 'users.name ASC'
).map(&:user)

With that, you’re telling the UserGroup model to find all rows based on the group ID, which you give it as the first parameter. You’re also telling it to eagerly load the associated rows from the ‘users’ table, ordering the results by the user’s name. Then, you’re using #map on the returned array to grab just the results of each row’s #user method. Thus, you end up with an array of User objects, all of whom belong to the group with ID #3.

If you just want to 1) find a single row and 2) have the single row returned (as opposed to an array with that row as its only element), use a #find_by_FIELD_NAME method, instead of a #find_all_by_FIELD_NAME:

1
UserGroup.find_by_user_id 1