Come si può ottenere un conteggio delle righe da has_many: attraverso le relazioni con: uniq => true

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

Domanda

Questo è il mio modello:

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

Tutti i rapporti stanno lavorando, ma ho un requisito aggiuntivo che non riesco a trovare la soluzione per:

considerare questa relazione nella classe Asset

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

chiamando Asset.find (: in primo luogo) .tags restituisce un array di Tag, come previsto, ma ho bisogno per ogni Tag per contenere un attributo count che indica quante volte la fila sarebbe apparsa se: uniq => true non è stato specificato.

ad es. più di un utente potrebbe applicare lo stesso tag a una risorsa. Mi piacerebbe per visualizzare il nome del tag più il numero di utenti che hanno applicato esso.

È stato utile?

Soluzione

Questo dovrebbe fare esattamente quello che vuoi.

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

In termini di righe restituite: group =>: id restituirà lo stesso set di: uniq => vero, ma permetterà anche di eseguire i calcoli desiderati. Questa affermazione è più manodopera rispetto:. Uniq => vero, così ho dato un nome diverso che consente di scegliere se prelevare i tag univoci con i loro conteggi raggruppate, o semplicemente l'elenco dei tag univoci

La dichiarazione di cui sopra si aggiunge l'attributo di frequenza per i record restituiti. Attraverso la magia del method_missing, è possibile accedere a quella con @ tag.frequency.

Utilizzo:

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

stamperà l'id, il nome e il numero di occorrenze di ogni tag per @asset.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top