web-dev-qa-db-fra.com

Vérifiez si un enregistrement existe du contrôleur dans Rails

Dans mon application, un utilisateur peut créer une entreprise. Quand ils déclenchent l'action index dans mon BusinessesController, je veux vérifier si une entreprise est liée au current_user.id:

  • Si oui: affichez l'entreprise.
  • Si non: redirigez vers l'action new.

J'essayais d'utiliser ceci:

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

Mais cela revient toujours vrai même lorsque l'entreprise n'existe pas ...

Comment puis-je tester si un enregistrement existe dans ma base de données?

77
user470763

Pourquoi votre code ne fonctionne pas?

La méthode where renvoie un objet ActiveRecord :: Relation (agit comme un tableau contenant les résultats de la where ), il peut être vide mais ce ne sera jamais 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

Comment tester s'il existe au moins un enregistrement?

Option 1: Utilisation de .exists?

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

Option 2: Utilisation de .present? (ou .blank? , l'opposé de .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: Affectation de variable dans l'instruction if

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

Cette option peut être considérée comme une odeur de code par certains linters (Rubocop par exemple).

Option 3b: Affectation de variable

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

Vous pouvez également utiliser .find_by_user_id(current_user.id) au lieu de .where(...).first


Meilleure option:

  • Si vous n'utilisez pas les objets Business: Option 1
  • Si vous devez utiliser le ou les objets Business: Option 3
209
MrYoshiji

Dans ce cas, j'aime bien utiliser le exists? méthode fournie par ActiveRecord:

Business.exists? user_id: current_user.id
26
Hamed

avec 'existe?':

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

avec 'any?':

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

Si vous utilisez quelque chose avec .where, veillez à éviter les problèmes avec les portées et à une meilleure utilisation de . Non masqué

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

ActiveRecord # où retournera un objet ActiveRecord :: Relation (qui ne sera jamais nul). Essayez d'utiliser .empty? sur la relation à tester si elle retournera des enregistrements.

1
Puhlze

Lorsque vous appelez Business.where(:user_id => current_user.id), vous obtenez un tableau. Ce tableau peut ne contenir aucun objet ou un ou plusieurs objets, mais il ne sera pas nul. Ainsi, la vérification == nil ne sera jamais vraie.

Vous pouvez essayer ce qui suit:

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

Donc, vous vérifiez le nombre d'éléments dans le tableau et les comparez à zéro.

ou vous pouvez essayer:

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

cela retournera un ou zéro.

1
marimaf

Je le ferais de cette façon si vous aviez besoin d'une variable d'instance de l'objet avec laquelle travailler:

if @business = Business.where(:user_id => current_user.id).first
  #Do stuff
else
  #Do stuff
end
0
user3633260
business = Business.where(:user_id => current_user.id).first
if business.nil?
# no business found
else
# business.ceo = "me"
end
0
Nino van Hooff