Check if record exists from controller in Rails

Ruby on-RailsRuby on-Rails-3ActiverecordExists

Ruby on-Rails Problem Overview


In my app a User can create a Business. When they trigger the index action in my BusinessesController I want to check if a Business is related to the current_user.id:

  • If yes: display the business.
  • If no: redirect to the new action.

I was trying to use this:

if Business.where(:user_id => current_user.id) == nil
  # no business found
end

But it always returns true even when the business doesn't exist...

How can I test if a record exists in my database?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

Why your code does not work?

The where method returns an ActiveRecord::Relation object (acts like an array which contains the results of the where), it can be empty but it will never be nil.

Business.where(id: -1) 
 #=> returns an empty ActiveRecord::Relation ( similar to an array )
Business.where(id: -1).nil? # ( similar to == nil? )
 #=> returns false
Business.where(id: -1).empty? # test if the array is empty ( similar to .blank? )
 #=> returns true

How to test if at least one record exists?

Option 1: Using .exists?

if Business.exists?(user_id: current_user.id)
  # same as Business.where(user_id: current_user.id).exists?
  # ...
else
  # ...
end

Option 2: Using .present? (or .blank?, the opposite of .present?)

if Business.where(:user_id => current_user.id).present?
  # less efficiant than using .exists? (see generated SQL for .exists? vs .present?)
else
  # ...
end

Option 3: Variable assignment in the if statement

if business = Business.where(:user_id => current_user.id).first
  business.do_some_stuff
else
  # do something else
end

This option can be considered a code smell by some linters (Rubocop for example).

Option 3b: Variable assignment

business = Business.where(user_id: current_user.id).first
if business
  # ...
else
  # ...
end

You can also use .find_by_user_id(current_user.id) instead of .where(...).first


Best option:

  • If you don't use the Business object(s): Option 1

  • If you need to use the Business object(s): Option 3

Solution 2 - Ruby on-Rails

In this case I like to use the exists? method provided by ActiveRecord:

Business.exists? user_id: current_user.id

Solution 3 - Ruby on-Rails

with 'exists?':

Business.exists? user_id: current_user.id #=> 1 or nil

with 'any?':

Business.where(:user_id => current_user.id).any? #=> true or false

If you use something with .where, be sure to avoid trouble with scopes and better use .unscoped

Business.unscoped.where(:user_id => current_user.id).any?

Solution 4 - Ruby on-Rails

ActiveRecord#where will return an ActiveRecord::Relation object (which will never be nil). Try using .empty? on the relation to test if it will return any records.

Solution 5 - Ruby on-Rails

When you call Business.where(:user_id => current_user.id) you will get an array. This Array may have no objects or one or many objects in it, but it won't be null. Thus the check == nil will never be true.

You can try the following:

if Business.where(:user_id => current_user.id).count == 0

So you check the number of elements in the array and compare them to zero.

or you can try:

if Business.find_by_user_id(current_user.id).nil?

this will return one or nil.

Solution 6 - Ruby on-Rails

business = Business.where(:user_id => current_user.id).first
if business.nil?
# no business found
else
# business.ceo = "me"
end

Solution 7 - Ruby on-Rails

I would do it this way if you needed an instance variable of the object to work with:

if @business = Business.where(:user_id => current_user.id).first
  #Do stuff
else
  #Do stuff
end

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser470763View Question on Stackoverflow
Solution 1 - Ruby on-RailsMrYoshijiView Answer on Stackoverflow
Solution 2 - Ruby on-RailsHamedView Answer on Stackoverflow
Solution 3 - Ruby on-Railsuser2427993View Answer on Stackoverflow
Solution 4 - Ruby on-RailsPuhlzeView Answer on Stackoverflow
Solution 5 - Ruby on-RailsmarimafView Answer on Stackoverflow
Solution 6 - Ruby on-RailsNino van HooffView Answer on Stackoverflow
Solution 7 - Ruby on-Railsuser3633260View Answer on Stackoverflow