Dans mon programme de rails actuel, lorsque j'utilise quelque chose comme
user = User.find(10)
Quand il n'y a pas d'utilisateur avec ID = 10, j'aurai une exception comme:
ActiveRecord::RecordNotFound: Couldn't find User with ID=10
Puis-je obtenir nil au lieu de lever une exception alors quand je fais quelque chose comme:
unless user = Challenge.find(10)
puts "some error msg"
end
Je veux juste être nul quand il n'y a pas d'enregistrements et que je ne veux pas utiliser begin / rescue
Merci
Réponses:
Oui, faites simplement:
Pour les rails 4 et 5:
la source
.find_by_*
retournerait nul et le.find
non.Something.find_by(id: x)
il créait une instruction SQL avec toutes les paires attribut / valeur du hachage dans le cadre de la clause WHERE. Cela ressemble à un bug de Rails pour moi.find_by_...
chercheurs dynamiques pour chaque attribut d'un modèle, y compris:id
. Donc,Challenge.find_by_id(10)
devrait fonctionner quelle que soit la version de Rails.Challenge.find(10) rescue nil
Dans Rails 4, les localisateurs dynamiques - tels que ceux
find_by_id
utilisés dans la réponse acceptée - étaient obsolètes.À l'avenir, vous devriez utiliser la nouvelle syntaxe:
la source
Challenge.find_by(id: 10)
est l'autre façon d'écrire cecivous pouvez le faire un peu hackish, utilisez simplement l'interface de requête ActiveRecord.
cela retournera nul, au lieu de lever une exception
la source
find_by_id
c'est qu'il est portable des rails 3 à 4. Dans les rails 4, c'estfind_by(:id => 10)
.Pourquoi n'attrapez-vous pas simplement l'exception? Votre cas ressemble exactement à quelles exceptions ont été faites:
Si vous souhaitez récupérer de l'erreur dans le bloc de secours (par exemple en définissant un utilisateur d'espace réservé (modèle nul)), vous pouvez continuer avec votre code sous ce bloc. Sinon, vous pourriez simplement mettre tout votre code pour le "happy case" dans le bloc entre "begin" et "rescue".
la source
begin…end
bloc, si vous avez déjà un bloc comme une méthode de contrôleur. Dans ce cas, la seule ligne supplémentaire dont vous avez besoin est larescue
ligne. Beaucoup plus élégant et plus facile à manipuler que la vérificationnil
avec uneif
déclaration.Vous pouvez essayer ceci
Challenge.exists?(10)
la source
Pour ceux qui luttent avec MongoId , il se trouve que les deux
find
et lesfind_by
méthodes soulèvera exception - peu importe votre version de rails!Il existe une option (à savoir, rise_not_found_error ) qui peut être définie sur false, mais lorsque falsey fait que la
find
méthode ne déclenche pas d'exception également.Ainsi, la solution pour les utilisateurs mongoïdes est le code dégoûtant:
la source
.where(email: params[:email]).first
me semble plus élégant que moi.rescue
syntaxe car elle peut masquer des problèmes tels que les fautes de frappeaussi simple que:
la source
if user...else
Vous pouvez utiliser find_by avec l'attribut requis (dans votre cas, l'id), cela retournera nil au lieu de donner une erreur si l'id donné n'est pas trouvé.
ou vous pouvez utiliser le nouveau format:
Vous pouvez également utiliser where mais vous devez savoir que where renvoie une relation d'enregistrement active avec zéro ou plusieurs enregistrements que vous devez d'abord utiliser pour ne renvoyer qu'un seul enregistrement ou nul si aucun enregistrement ne retourne.
la source