2012-02-29 11 views
6

Ho un modello di post con i commenti has_many. Ogni post ha un ID thread (ma non esiste un modello denominato Thread).ActiveRecord: contare con i gruppi

Quindi, se voglio contare il numero di thread in questo post mi si dovrebbe occupare come

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

E questo funziona benissimo. Ma cosa succede se voglio contare il numero di thread con un solo commento?

> 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 

Quindi ho OrderedHash invece di numero intero. E devo fare il passo non necessario

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

Esiste una soluzione migliore?

risposta

12

Questo è il comportamento previsto.

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

Questo restituisce un hash in cui la chiave è l'id del thread e il valore è il conteggio. Credo che questo sia il caso ogni volta che fai un gruppo con una funzione aggregata in rotaie. È necessario eseguire il secondo conteggio per ottenere il numero di risultati corrispondenti alla prima query.

io non sono sicuro di come questo aspetto del lavoro in Rails, ma qui è la SQL che Penso che si desidera:

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 si aspetta "=" non "==" per equivalenza. La tua risposta è probabilmente corretta per alcune marche di SQL ma fallisce su MySQL senza questa modifica. –

+0

Questo è corretto. Tuttavia stavo cercando di essere coerente con il formato che stava usando nel post originale. – Brad

Problemi correlati