Comment peut-on obtenir un nombre de lignes de has_many: à travers les relations avec: uniq => true

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

Question

Ceci est mon modèle:

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

Toutes les relations travaillent mais j'ai une exigence supplémentaire que je ne peux pas trouver la solution pour:

considérer cette relation dans la classe d'actifs

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

appelant Asset.find (: en premier) .tags retourne un tableau de balises comme prévu mais j'ai besoin pour chaque balise pour contenir un attribut de comptage indiquant combien de fois la ligne serait apparu si: uniq => true n'a pas été spécifié.

par exemple. plus d'un utilisateur peut appliquer la même étiquette à un actif. Je voudrais afficher le nom de la balise ainsi que le nombre d'utilisateurs qui l'ont appliqué.

Était-ce utile?

La solution

Cela devrait faire exactement ce que vous voulez.

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

En termes de lignes retournées: groupe =>: id retourne le même ensemble que: uniq => vrai, mais il vous permettra également d'effectuer les calculs que vous voulez. Cette déclaration est plus de travail que:. Uniq => true, donc je lui ai donné un nom différent, vous permettant de choisir de récupérer les étiquettes uniques avec leurs comptes groupés, ou tout simplement la liste des balises uniques

La déclaration ci-dessus ajoutera l'attribut de fréquence aux enregistrements renvoyés. Grâce à la magie de method_missing, vous pouvez accéder à ce avec @ tag.frequency.

Utilisation:

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

imprimera le id, le nom et le nombre d'occurrences de chaque balise pour @asset.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top