Rails active la asociación de consultas de registros con ‘exists’

Estoy trabajando en una aplicación que permite a los miembros realizar una encuesta (el miembro tiene una relación de uno a varios con la respuesta). Response contiene el member_id, question_id y su respuesta.

La encuesta se envía completa o nula, por lo que si hay registros en la tabla de respuestas para ese miembro, han completado la encuesta.

Mi pregunta es, ¿cómo volver a escribir la consulta a continuación para que realmente funcione? En SQL, este sería un candidato principal para la palabra clave EXISTS.

def surveys_completed members.where(responses: !nil ).count end 

Puede usar includes y luego probar si la (s) respuesta (s) relacionada (s) existe (s) de esta manera:

 def surveys_completed members.includes(:responses).where('responses.id IS NOT NULL') end 

Aquí hay una alternativa, con joins :

 def surveys_completed members.joins(:responses) end 

La solución usando Rails 4 :

 def surveys_completed members.includes(:responses).where.not(responses: { id: nil }) end 

Preguntas similares:

  • ¿Cómo consultar un modelo basado en el atributo de otro modelo que pertenece al primer modelo?
  • asociación llamada no encontrada tal vez con errores ortográficos en la asociación de Rails
  • Rails 3, has_one / has_many con la condición lambda
  • Rails 4 scope para encontrar padres sin hijos
  • Unir múltiples tablas con registros activos

Puede usar la palabra clave SQL EXISTS de forma elegante Rails-ish usando Where Exists gem:

 members.where_exists(:responses).count 

Por supuesto, también puedes usar SQL sin formato:

 members.where("EXISTS" \ "(SELECT 1 FROM responses WHERE responses.member_id = members.id)"). count 

También puede usar una subconsulta:

 members.where(id: Response.select(:member_id)) 

En comparación con algo que includes , no cargará los modelos asociados (que es un beneficio de rendimiento si no los necesita).