Vérifiez si l'enregistrement existe à partir du contrôleur dans Rails
Dans mon application, un Utilisateur peut créer une Entreprise. Quand ils déclenchent le index
action dans mon BusinessesController
je veux vérifier si une Entreprise est liée à la current_user.id
:
- Si oui: afficher l'entreprise.
- Si non: rediriger vers l'action
new
.
J'essayais d'utiliser ceci:
if Business.where(:user_id => current_user.id) == nil
# no business found
end
Mais il retourne toujours vrai même lorsque l'entreprise n'existe pas...
Comment puis-je tester si un enregistrement existe dans ma base de données?
7 réponses
Pourquoi votre code ne fonctionne pas?
Le where
méthode retourne un ActiveRecord::Relation objet (agit comme un tableau qui contient les résultats de l'where
), il peut être vide, mais il 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 si au moins un enregistrement existe?
Option 1: À L'Aide De .exists?
if Business.exists?(user_id: current_user.id)
# same as Business.where(user_id: current_user.id).exists?
# ...
else
# ...
end
Option 2: à l'Aide 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 variables
business = Business.where(user_id: current_user.id).first
if business
# ...
else
# ...
end
Vous pouvez aussi utiliser .find_by_user_id(current_user.id)
au lieu de .where(...).first
Meilleure option:
- si vous n'utilisez pas le (s) objet (s)
Business
: Option 1 - si vous avez besoin d'utiliser le(s) objet (s): Option 3
Dans ce cas, j'aime utiliser la méthode exists?
fournie par ActiveRecord:
Business.exists? user_id: current_user.id
Avec ' existe?':
Business.exists? user_id: current_user.id #=> 1 or nil
, Avec 'tout?':
Business.where(:user_id => current_user.id).any? #=> true or false
Si vous utilisez quelque chose avec .où, assurez-vous d'éviter les problèmes avec les étendues et une meilleure utilisation .non délimité
Business.unscoped.where(:user_id => current_user.id).any?
ActiveRecord # where retournera un objet ActiveRecord::Relation (qui ne sera jamais nul). Essayez d'utiliser .est-il vide? sur la relation à tester si elle retournera des enregistrements.
Lorsque vous appelez Business.where(:user_id => current_user.id)
, vous obtiendrez un tableau. Ce tableau peut ne pas avoir d'objets ou un ou plusieurs objets, mais il ne sera pas null. Ainsi, le chèque = = nil ne sera jamais vrai.
Vous pouvez essayer ce qui suit:
if Business.where(:user_id => current_user.id).count == 0
Vous vérifiez donc 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 renverra un ou zéro.
business = Business.where(:user_id => current_user.id).first
if business.nil?
# no business found
else
# business.ceo = "me"
end
Je le ferais de cette façon si vous aviez besoin d'une variable d'instance de l'objet pour travailler avec:
if @business = Business.where(:user_id => current_user.id).first
#Do stuff
else
#Do stuff
end