¿Cómo se puede obtener un recuento de filas de has_many: a través de las relaciones con: uniq => true

StackOverflow https://stackoverflow.com/questions/2199338

Pregunta

Esta es mi modelo:

class Tag < ActiveRecord::Base
  # id, name
  has_many :taggings
end

class Tagging < ActiveRecord::Base
  # id, tag_id, owner_id, target_type, target_id
  belongs_to :tag
  belongs_to :owner, :class_name => 'User'
  belongs_to :target, :polymorphic => true
  validates_uniqueness_of :tag_id, :scope => [ :target_id, :target_type, :owner_id ]
end

class Asset < ActiveRecord::Base
  # id, owner_id, title, type, etc
  belongs_to :owner, :class_name => 'User'
  has_many :taggings, :as => :target
  has_many :taggers, :through => :taggings, :source => :owner, :uniq => true
  has_many :tags, :through => :taggings, :uniq => true
end

class User < ActiveRecord::Base
  # id, name, email, etc
  has_many :assets, :foreign_key => 'owner_id'
  has_many :my_taggings, :class_name => 'Tagging', :foreign_key => 'owner_id'
  has_many :my_tags, :through => :my_taggings, :source => :tag, :uniq => true
  has_many :taggings, :as => :target
  has_many :taggers, :through => :taggings, :source => :owner, :uniq => true
  has_many :tags, :through => :taggings, :uniq => true
end

Todas las relaciones están trabajando pero tiene un requisito adicional que no puedo encontrar la solución para:

en cuenta esta relación en la clase de activos

has_many :tags, :through => :taggings, :uniq => true

llamando Asset.find (: en primer lugar) .tags devuelve una matriz de etiquetas como se esperaba pero necesito para cada etiqueta para contener un atributo de recuento que indica cuántas veces habría aparecido la fila si: uniq => cierto no se especificó.

por ejemplo. más de un usuario podría aplicar la misma etiqueta a un Activo. Me gustaría mostrar la etiqueta con su nombre más el número de usuarios que se aplicaban a él.

¿Fue útil?

Solución

Esto debería hacer exactamente lo que quiere.

has_many :tags_with_count, :source => :tag, :through => :taggings, 
  :group => "tags.id", :joins => :taggings,
  :select = "tags.*, COUNT('taggings.id') AS frequency"

En términos de filas devueltas: Grupo =>: Identificación del devolverá el mismo conjunto que: uniq => cierto, pero también le permitirá realizar los cálculos que desee. Esta declaración es más mano de obra que:. Uniq => verdadero, así que le he dado un nombre diferente que le permite elegir si desea recuperar las etiquetas únicas con sus recuentos agrupados, o simplemente la lista de etiquetas únicas

La declaración anterior se sumará el atributo de frecuencia de los registros devueltos. A través de la magia de method_missing, puede acceder a que con @ tag.frequency.

Uso:

@tags = @asset.tags_with_count
@tags.each{|tag| puts [tag.id, tag.name. tag.frequency].join "\t"}

imprimirá el ID, el nombre y número de ocurrencias de cada etiqueta para @asset.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top