2012-02-29 23 views
6

Tengo un modelo de publicación con has_many comentarios. Cada publicación tiene una identificación de subproceso (pero no hay ningún modelo llamado Subproceso).ActiveRecord: cuente con grupos

Así que si quiero contar el número de hilos en este post me SMTH como

> post.comments.count(:thread, :distinct => true) 
SELECT COUNT(DISTINCT "comments"."thread") FROM "comments" WHERE "comments"."post_id" = 3 

Y esto funciona bien. Pero, ¿y si quiero contar la cantidad de hilos con un solo comentario?

> post.comments.group(:thread).having('COUNT(*) == 1').count 
SELECT COUNT(*) AS count_all, thread AS thread FROM "comments" WHERE "comments"."post_id" = 3 GROUP BY thread HAVING COUNT(*) == 1 ORDER BY id 

Así que tengo un OrderedHash en lugar de Entero. Y tengo que hacer el paso innecesario

> post.comments.group(:thread).having('COUNT(*) == 1').count.count 

¿Hay alguna solución mejor?

Respuesta

12

Se espera que esto suceda.

post.comments.group(:thread).having('COUNT(*) == 1').count 

Esto está volviendo un hash donde la clave es el ID del tema y el valor es el recuento. Creo que este es el caso cada vez que haces un grupo con una función agregada en rieles. Debe hacer el segundo recuento para obtener el número de resultados que coincide con la primera consulta.

No estoy seguro de cómo se vería en los carriles, pero aquí está el SQL que creo que quiere:

SELECT COUNT(*) FROM 
    SELECT COUNT(*) AS count_all, thread AS thread 
    FROM "comments" 
    WHERE "comments"."post_id" = 3 
    GROUP BY thread 
    HAVING COUNT(*) == 1 
    ORDER BY id 
+0

Generalmente SQL espera "=" no "==" para la equivalencia. Su respuesta probablemente sea correcta para algunas marcas de SQL, pero falla en MySQL sin este cambio. –

+0

Eso es correcto. Sin embargo, estaba tratando de ser coherente con el formato que estaba usando en la publicación original. – Brad