Comment sélectionner où ID dans Array Rails ActiveRecord sans exception
-
10-07-2019 - |
Question
Quand j'ai un tableau d'identifiants, comme
ids = [2,3,5]
et j'effectue
Comment.find(ids)
tout fonctionne bien. Mais quand il y a un identifiant qui n'existe pas, j'obtiens une exception. Cela se produit généralement lorsque je reçois une liste d’ID correspondant à certains filtres et que je fais quelque chose comme
current_user.comments.find(ids)
Cette fois, je peux avoir un identifiant de commentaire valide, qui n'appartient cependant pas à un utilisateur donné. Il est donc introuvable et une exception me parvient.
J'ai essayé find (: all, ids)
, mais tous les enregistrements sont renvoyés.
La seule façon dont je peux le faire maintenant est
current_user.comments.select { |c| ids.include?(c.id) }
Mais cela me semble une solution super inefficace.
Existe-t-il un meilleur moyen de sélectionner ID dans un tableau sans exception sur un enregistrement inexistant?
La solution
S'il s'agit simplement d'éviter l'exception qui vous préoccupe, le "find_all_by .." La famille de fonctions fonctionne sans exception.
Comment.find_all_by_id([2, 3, 5])
fonctionnera même si certains identifiants n'existent pas. Cela fonctionne dans le
user.comments.find_all_by_id(potentially_nonexistent_ids)
le cas aussi.
Mise à jour: Rails 4
Comment.where(id: [2, 3, 5])
Autres conseils
Mise à jour: cette réponse est plus pertinente pour Rails 4.x
Faites ceci:
current_user.comments.where(:id=>[123,"456","Michael Jackson"])
Le point fort de cette approche est qu'elle renvoie un objet Relation
, auquel vous pouvez joindre plusieurs clauses .where
, .limit
. clauses, etc., ce qui est très utile. Il permet également des identifiants inexistants sans générer d'exceptions.
La nouvelle syntaxe Ruby serait:
current_user.comments.where(id: [123, "456", "Michael Jackson"])
Si vous avez besoin de plus de contrôle (vous devez peut-être indiquer le nom de la table), vous pouvez également procéder comme suit:
Model.joins(:another_model_table_name)
.where('another_model_table_name.id IN (?)', your_id_array)
Les méthodes .find et .find_by_id sont désormais obsolètes dans les rails 4. Nous pouvons donc utiliser ci-dessous:
Comment.where(id: [2, 3, 5])
Cela fonctionnera même si certains identifiants n'existent pas. Cela fonctionne dans le
user.comments.where(id: avoided_ids_array)
Aussi pour exclure les identifiants
Comment.where.not(id: [2, 3, 5])
Pour éviter que des exceptions ne détruisent votre application, vous devez intercepter ces exceptions et les traiter comme vous le souhaitez, en définissant le comportement de votre application dans les situations où l'identifiant n'est pas trouvé.
begin
current_user.comments.find(ids)
rescue
#do something in case of exception found
end
Voici plus d'informations sur les exceptions en ruby.
Vous pouvez également l'utiliser dans named_scope si vous voulez y mettre d'autres conditions
Par exemple, incluez un autre modèle:
named_scope 'get_by_ids', lambda {| ids | {: include = > [: commentaires],: conditions = > [" comments.id IN (?) " ,, ids]}}