Tag Cloud on rails?

Mike Dershowitz wrote:


Anyone know of anyone that's implemented AND made available a tag cloud
implemented in rails?



Like Michael, I'm using acts_as_taggable and adding a method to the Tag model but implementing it slightly differently. I'm pasting the code as is (and just looking at it fresh, it could be improved in places), but not all of it is needed (e.g. I needed to be able to restrict the tag cloud to certain models, and those lines are commented as optional

  def self.tag_cloud_count(options={})
    except, only = options[:except].to_a, options[:only].to_a # optional
    raise ArgumentError, "You can only specify :except OR :only options" if !except.empty? && !only.empty? # optional conditions = "taggings.tag_id = tags.id" if except.empty? && only.empty?
    conditions = ["(taggings.tag_id = tags.id) AND (taggings.taggable_type IN (?))", only.collect {|m| m.to_s.classify }] if !only.empty? # optional
    conditions = ["(taggings.tag_id = tags.id) AND (taggings.taggable_type NOT IN (?))", except.collect {|m| m.to_s.classify }] if !except.empty? # optional
    find(:all, :select => "tags.*, COUNT(*) AS tag_count", :joins => "INNER JOIN taggings", :conditions => conditions, :group => "tags.name", :order => "tags.name ASC")

Then in my app helper:
  def tag_cloud_for(tag_cloud)
    max_tag_count = tag_cloud.max {|a,b| a.tag_count.to_i <=> b.tag_count.to_i }.tag_count.to_f
    min_tag_count = tag_cloud.min {|a,b| a.tag_count.to_i <=> b.tag_count.to_i }.tag_count.to_f
    min_font_size = 1.0
    max_font_size = 2.5
    mult = (max_font_size - min_font_size)/(max_tag_count - min_tag_count)
    output = tag_cloud.collect { |tag| link_to( tag.name,
                                                {:controller => 'search', :tag => tag.name}, {:style => "font-size: #{(((tag.tag_count.to_f - min_tag_count) * mult) + min_font_size)}em"}) }
    output.join(" ")

In the helper method above the argument of the method is simply the collection of tags returned by to tag_cloud_count method. The cloud is output as a set of links, which go to my search controller, which returns all items tagged with the given term.

Of course, YMMV, but hopefully between this and Michael's solution you should be able to find something that suits.