web-dev-qa-db-fra.com

Comment sélectionner où ID dans Array Rails ActiveRecord sans exception

Quand j'ai un tableau d'identifiants, comme

ids = [2,3,5]

et je joue

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 ID de commentaire valide, qui n'appartient cependant pas à un utilisateur donné. Il n'est donc pas trouvé et une exception me parvient.

J'ai essayé find(:all, ids), mais il renvoie tous les enregistrements.

Le seul moyen de 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 Array sans obtenir d'exception pour un enregistrement non existant?

122
Jakub Arnold

S'il s'agit simplement d'éviter les exceptions qui vous inquiètent, la famille de fonctions "find_all_by .." 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)

cas aussi.

Mise à jour: Rails 4

Comment.where(id: [2, 3, 5])
198
prismofeverything

Mise à jour: Cette réponse est plus pertinente pour Rails 4.x

Faire 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 davantage de clauses .where, De clauses .limit, Etc., ce qui est très utile. Il permet également des identifiants inexistants sans générer d'exceptions.

La nouvelle syntaxe Ruby serait la suivante:

current_user.comments.where(id: [123, "456", "Michael Jackson"])
144
mjnissim

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)
18
Jonathan Lin

Maintenant, les méthodes .find et .find_by_id sont obsolètes dans 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 ID

Comment.where.not(id: [2, 3, 5])
10
Sumit Munot

Pour éviter que des exceptions ne tue 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'infos sur les exceptions en Ruby.

1
rogeriopvl

Vous pouvez aussi l'utiliser dans named_scope si vous voulez y mettre d'autres conditions

par exemple inclure un autre modèle:

named_scope 'get_by_ids', lambda {| ids | {: include => [: commentaires],: conditions => ["comments.id IN (?)", ids]}}

0
mtfk