2012-06-08 14 views
9

Ho un'applicazione in cui è possibile elencare elementi e aggiungere tag a ciascun articolo. I modelli Articoli e Tag sono associati in questo modo:Rails 3 Ordina per conteggio has_many: tramite

class Item < ActiveRecord::Base 
    has_many :taggings 
    has_many :tags, :through => :taggings 
end 

class Tagging < ActiveRecord::Base 
    belongs_to :item 
    belongs_to :tag 
end 

class Tag < ActiveRecord::Base 
    has_many :taggings 
    has_many :items, :through => :taggings 
end 

Quindi, questo molti-a-molti mi permette di impostare n tag per ogni articolo, e lo stesso tag possono essere utilizzati parecchie volte.

Vorrei elencare tutti i tag ordinati per numero di elementi associati a questo tag. Tag più utilizzati, mostra prima. Meno usato, ultimo.

Come posso farlo?

Saluti.

risposta

8
Tag.joins(:taggings).select('tags.*, count(tag_id) as "tag_count"').group(:tag_id).order(' tag_count desc') 

provare disc, asc e vedere la differenza.

Abbiamo bisogno selezionare, per avere colonna tag_count, e abbiamo bisogno di colonna tag_count applicare fine ad esso, il resto tutto dritto in avanti uniscono e raggruppamento.

Btw, perchè non provare questo fuori https://github.com/mbleigh/acts-as-taggable-on

+0

La ringrazio molto per il vostro aiuto. E proverò quel plugin. – goo

+0

+1 Am. Hai qualche idea su come ottenere lo stesso risultato della query ma con un altro livello di has_many attraverso :? La mia domanda [http://stackoverflow.com/questions/19537378/ordering-nested-has-many-through-by-count-of-associations] sarebbe analoga agli articoli goo che sono membri dei gruppi, quindi proviamo ad elencare i tag di un singolo gruppo di articoli in ordine di frequenza di utilizzo all'interno del gruppo, piuttosto che tra tutti gli articoli. Grazie! –

3

Spero che ci sia un modo migliore, ma questo ha funzionato per me (senza lo spazio bianco). Si supponga che name sia l'attributo nome del modello Tag.

foo = Tagging.select("name, count(item_id) as item_count") 
     .joins("inner join tags on taggings.tag_id = tags.id") 
     .group("name") 
     .order("item_count DESC") 

foo.each { |r| puts "number of items tagged #{r.name}: #{r.item_count}"} 

-->"number of items tagged Bieber: 100" 
-->"number of items tagged GofT: 99"