find vs exists in rails

When want want to find a record/document using our favorite ORM’s like ActiveRecord or Mongoid, we make use of the find method.

find()
In ActiveRecord, find returns the record if found else it returns nil

2.3.1 :005 > User.find_by(email: 'a@b.com')
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT ? [["email", "a@b.com"], ["LIMIT", 1]]
=> #
2.3.1 :006 > User.find_by(email: 'b@b.com')
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."email" = ? LIMIT ? [["email", "b@b.com"], ["LIMIT", 1]]
=> nil

In Mongoid, find returns a record if found else it raises Mongoid::Errors::DocumentNotFound


:003 > User.find_by(email: 'a@b.com')
=> #
:004 > User.find_by(email: 'b@b.com')
Mongoid::Errors::DocumentNotFound:
message:
Document not found for class User with attributes {:email=>"b@b.com"}.
summary:
When calling User.find_by with a hash of attributes, all attributes provided must match a document in the database or this error will be raised.
resolution:
Search for attributes that are in the database or set the Mongoid.raise_not_found_error configuration option to false, which will cause a nil to be returned instead of raising this error.

When you get this error, if you want the similar behavior of find as its in ActiveRecord i.e. find should return nil if document is not found `please do not set raise_not_found_error to false` in mongoid.yml, instead change your query.

exists?()

In ActiveRecord and Mongoid, exists? returns true if record/ document is found and returns false else wise.

ActiveRecord –

2.3.1 :007 > User.exists?(email: 'b@b.com')
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ? [["email", "b@b.com"], ["LIMIT", 1]]
=> false
2.3.1 :008 > User.exists?(email: 'a@b.com')
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ? [["email", "a@b.com"], ["LIMIT", 1]]
=> true

Mongoid –


:002 > User.where(email: 'a@b.com').exists?
=> true
:003 > User.where(email: 'b@b.com').exists?
=> false

In Mongoid when we want to check if the document exist with the given conditions and we do not want to our query to raise Mongoid::Errors::DocumentNotFound we should use exists?() method, which returns true if document found and returns false else wise.

Leave a comment