Wie kann man eine Zeilenanzahl von has_many erhalten: durch die Beziehungen: Uniq => true
-
25-09-2019 - |
Frage
Das ist mein Modell:
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
Alle der Beziehungen arbeiten, aber ich habe eine zusätzliche Anforderung, dass ich nicht die Lösung finden kann:
Sehen Sie diese Beziehung in der Asset-Klasse
has_many :tags, :through => :taggings, :uniq => true
Aufruf Asset.find (: first) .tags gibt einen Array von Variablen wie erwartet, aber ich brauche für jeden Tag eine Zählung Attribut enthalten die angibt, wie oft die Reihe erschienen wäre, wenn: Uniq => true wurde nicht angegeben.
zB. mehr als ein Benutzer den gleichen Tag zu einem Asset-Anwendung finden könnte. Ich möchte den Tag-Namen und die Anzahl der Nutzer anzuzeigen, die es angewendet wird.
Lösung
Dies sollte genau das tun, was Sie wollen.
has_many :tags_with_count, :source => :tag, :through => :taggings,
:group => "tags.id", :joins => :taggings,
:select = "tags.*, COUNT('taggings.id') AS frequency"
In Bezug auf den zurückgegebenen Zeilen: group =>: id wird den gleichen Satz zurück, wie: Uniq => true, aber es wird auch ermöglicht es Ihnen, die Berechnungen, die Sie ausführen möchten. Diese Aussage ist arbeitsintensiver als:. Uniq => true, so dass ich ihm einen anderen Namen gegeben habe, so dass Sie wählen, ob die eindeutigen Tags mit ihrem gruppierte zählt, oder einfach nur die Liste der einzigartigen Tags holen
Die obige Aussage wird die Frequenz-Attribut auf die zurückgegebenen Datensätze hinzufügen. Durch die Magie von method_missing, können Sie das Zugriff mit @ tag.frequency.
Verbrauch:
@tags = @asset.tags_with_count
@tags.each{|tag| puts [tag.id, tag.name. tag.frequency].join "\t"}
Wird die ID, Namen und Anzahl des Auftretens jeden Tag für @asset drucken.