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

Quand j’ai un tableau d’id, comme

ids = [2,3,5] 

et je joue

 Comment.find(ids) 

tout fonctionne bien. Mais quand il n’y a pas d’identifiant, j’obtiens une exception. Cela se produit généralement quand je reçois la liste des identifiants qui correspondent à un filtre 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 toutefois pas à un utilisateur donné, donc il n’est pas trouvé et je reçois une exception.

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

La seule façon dont je peux le faire maintenant est

 current_user.comments.select { |c| ids.include?(c.id) } 

Mais cela me semble être une solution super inefficace.

Existe-t-il un meilleur moyen de sélectionner l’ ID dans le tableau sans obtenir d’exception sur les enregistrements non existants?

Si vous évitez simplement l’exception qui vous préoccupe, la famille de fonctions “find_all_by ..” fonctionne sans lancer d’exception.

 Comment.find_all_by_id([2, 3, 5]) 

fonctionnera même si certains des 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]) 

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

Faites ceci:

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

Le côté le plus fort de cette approche est qu’elle renvoie un object Relation auquel vous pouvez joindre plus de clauses .limit clauses .limit , etc., ce qui est très utile. Il permet également des identifiants inexistants sans jeter 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 effectuer les opérations suivantes:

 Model.joins(:another_model_table_name) .where('another_model_table_name.id IN (?)', your_id_array) 

Désormais, les méthodes .find et .find_by_id sont obsolètes dans les rails 4. Au lieu de cela, nous pouvons utiliser ci-dessous:

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

Cela fonctionnera même si certains des 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]) 

Pour éviter les exceptions qui tuent votre application, vous devriez intercepter ces exceptions et les traiter comme vous le souhaitez, en définissant le comportement de votre application dans les situations où l’ID 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 dans Ruby.

Vous pouvez également 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 => [: comments],: conditions => [“comments.id IN (?)”, ids]}}