Je travaille sur une application qui permet aux membres de répondre à un sondage (le membre a une relation un à plusieurs avec la réponse). La réponse contient le member_id, question_id et leur réponse.
L’enquête est soumise à tout ou rien. Par conséquent, s’il existe des enregistrements dans le tableau des réponses pour ce membre, ils ont rempli le questionnaire.
Ma question est la suivante: comment réécrire la requête ci-dessous pour qu’elle fonctionne réellement? En SQL, ce serait un candidat de choix pour le mot clé EXISTS.
def surveys_completed members.where(responses: !nil ).count end
Vous pouvez utiliser includes
et ensuite tester si la ou les réponses associées existent comme ceci:
def surveys_completed members.includes(:responses).where('responses.id IS NOT NULL') end
Voici une alternative, avec des joins
:
def surveys_completed members.joins(:responses) end
La solution utilisant Rails 4 :
def surveys_completed members.includes(:responses).where.not(responses: { id: nil }) end
Questions similaires:
Vous pouvez utiliser le mot-clé SQL EXISTS
de manière élégante à l’aide de Rails-ish en utilisant le gem de Where Exists :
members.where_exists(:responses).count
Bien entendu, vous pouvez également utiliser du SQL brut:
members.where("EXISTS" \ "(SELECT 1 FROM responses WHERE responses.member_id = members.id)"). count
Vous pouvez également utiliser une sous-requête:
members.where(id: Response.select(:member_id))
Par rapport à quelque chose avec des includes
il ne chargera pas les modèles associés (ce qui est un avantage de performance si vous n’en avez pas besoin).