How to get line count from has_many: through relationships with: uniq => true

This is my model:

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 

All relationships work, but I have an additional requirement that I cannot find a solution for:

consider this relation in the Asset class

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

calling Asset.find (: first) .tags returns an array of tags as expected, but I need each tag to contain a count attribute, indicating how many times the line would appear if: uniq => true is not specified.

eg. more than one user can apply the same tag to an object. I would like to show the name of the tag plus the number of users who used it.

+6
ruby-on-rails activerecord has-many-through
source share
1 answer

This should do exactly what you want.

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

In terms of the returned strings: group =>: id will return the same set as: uniq => true, but it will also allow you to perform the necessary calculations. This statement is more time consuming than: uniq => true, so I gave it a different name to choose whether to get unique tags with their grouped counts or just a list of unique tags.

The above statement will add a frequency attribute to the returned records. With the magic_ method, you can access this @ tag.frequency app.

Using:

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

The identifier, name and number of occurrences of each tag for @asset will be printed.

+5
source share

All Articles