Check if an entry from the controller exists in Rails

In my application, the user can create a business. When they run the index action in my BusinessesController , I want to check if the business is associated with current_user.id :

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

I tried to use this:

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

But it always returns true, even if the business does not exist ...

How to check if an entry exists in my database?

+56
ruby-on-rails activerecord exists ruby-on-rails-3
May 22 '13 at 2:49
source share
7 answers

Why is your code not working?

The where method returns an ActiveRecord :: Relation object (acts like an array containing the results of where ), it may 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 check 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? opposite .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: Assigning a variable in an if statement

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

This parameter can be considered a smell of code by some linter (for example, Rubocop).

Option 3b: Assigning Variables

 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




The best way:

  • If you are not using a Business object: Option 1
  • If you need to use Business objects: Option 3
+170
May 22 '13 at 2:53
source share

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

 Business.exists? user_id: current_user.id 
+24
Jun 26 '13 at 17:34
source share

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 issues with areas and use it better . unscoped

 Business.unscoped.where(:user_id => current_user.id).any? 
+3
Aug 21 '13 at 9:39 on
source share

ActiveRecord # where the ActiveRecord :: Relation object will be returned (which will never be zero). Try to use. Way? on the relation to the test, if it returns any records.

+1
May 22 '13 at 3:01
source share

When you call Business.where(:user_id => current_user.id) , you will get an array. This array cannot contain objects or one or more objects, but it will not be empty. So 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 with zero.

or you can try:

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

this will return one or zero.

+1
May 22 '13 at 3:07
source share
 business = Business.where(:user_id => current_user.id).first if business.nil? # no business found else # business.ceo = "me" end 
0
Mar 19 '15 at 11:06
source share

I would do it like this if you need an object instance variable to work with:

 if @business = Business.where(:user_id => current_user.id).first #Do stuff else #Do stuff end 
0
Mar 16 '16 at 15:45
source share



All Articles