Solution 1:

  • where returns an ActiveRecord::Relation (not an array, even though it behaves much like one), which is a collection of model objects. If nothing matches the conditions, it simply returns an empty relation.

  • find (and its related dynamic find_by_columnname methods) returns a single model object. If nothing is found, an ActiveRecord::RecordNotFound exception is raised (but not with the dynamic find_by_ methods).

    While find can return an Array of records—not a Relation—if given a list of IDs, using where is preferred since Rails 3. Many similar uses of find are now deprecated or gone entirely.

So yes, if you only want and expect a single object, using find is easier, as otherwise you must call Model.where.first.

Note that old-style hash options to find and many dynamic find_ methods are deprecated as of Rails 4.0 (see relevant release notes).

Solution 2:

Actually find_by takes a model object from where obtained ActiveRecord::Relation

def find_by(*args)
  where(*args).take
end

Source

Solution 3:

Model.find is using the primary key column. Therefore there is always exactly one or no result. Use it when you are looking for one specific element identified by it's id.