2012-06-08 12 views
9

Tengo una aplicación donde puedo enumerar elementos y agregar etiquetas a cada artículo. Los modelos Artículos y Etiquetas se asocian así:Rieles 3 Ordene por cuenta en has_many: a través de

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 

Por lo tanto, esto muchos-a-muchos relación me permite establecer n etiquetas para cada artículo, y la misma etiqueta se pueden usar varias veces.

Me gustaría mostrar una lista de todas las etiquetas ordenadas por el número de elementos asociados con esta etiqueta. Más etiquetas usadas, muestra primero. Menos usado, último.

¿Cómo puedo hacer eso?

Atentamente.

Respuesta

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

probarlo desc asc y vea la diferencia.

Necesitamos seleccionar , tener la columna tag_count, y necesitamos la columna tag_count aplicar fin a la misma, descansar toda sencillo unen y agrupación.

Por cierto, ¿por qué no intenta esto https://github.com/mbleigh/acts-as-taggable-on

+0

muchas gracias por su ayuda. Y probaré ese complemento. – goo

+0

+1 Amol. ¿Tiene alguna idea sobre cómo lograr este mismo resultado de consulta pero con otra capa de has_many a través de :? Mi pregunta [http://stackoverflow.com/questions/19537378/ordering-nested-has-many-through-by-count-of-associations] sería análoga a los elementos de goo que son miembros de Grupos, y luego intentar listar las Etiquetas de un grupo de artículos individual en orden de su frecuencia de uso dentro del grupo, en lugar de entre todos los artículos. ¡Gracias! –

3

Espero que haya una mejor manera, pero esto funcionó para mí (sin espacio en blanco). Supongamos name es el atributo de nombre del modelo de etiqueta.

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" 
Cuestiones relacionadas