Forum: Ruby on Rails Tag Cloud on rails?

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
Mike D. (Guest)
on 2007-02-14 01:24

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


Michael S. (Guest)
on 2007-02-14 01:59
(Received via mailing list)
On Wednesday 14 February 2007, Mike D. wrote:
> Hi:
> Anyone know of anyone that's implemented AND made available a tag
> cloud implemented in rails?

Here's what I'm using with Acts As Taggable (On Steroids).

I've added a method to the Tag model class for retrieving the N most
popular tags

  def self.find_most_popular(max_count = 0)
    count_col = Tag.connection.quote_column_name('count')
    sql =   "SELECT AS id, AS name, COUNT(*) AS
    sql <<  " FROM taggings JOIN tags ON taggings.tag_id ="
    sql <<  " GROUP BY tag_id ORDER BY #{count_col} DESC"
    sql <<  " LIMIT #{max_count.to_i}" if max_count.to_i > 0
    tags = Tag.find_by_sql(sql)
    tag_count = tags.size
    tags.each do |tag|
      tag.send(:write_attribute, :percentage, (tag.count * 100) /

Acts As Taggable On Steroids has some other functionality for this, see
its REAME.

In the PopularTagsHelper I have a method like this

  def popular_tag(t, options = {})
    wrap = options[:wrap] || 'span'
    font_size   = t.percentage * (options[:size_scale]   || 12)
    font_weight = t.percentage * (options[:weight_scale] || 10)
    font_size   = [font_size, options[:min_size]].max if
    font_size   = [font_size, options[:max_size]].min if
      link_to(, ''),
      :title => "#{t.count} times",
      :class => options[:class],
      :style => "font-size:#{font_size}%;font-weight:#{font_weight}%"

In the view

  <ul class="tagcloud">
  <% @popular_tags.sort_by(&:name).each do |t| -%>
    <%= popular_tag(t, :wrap => 'li', :min_size => 30, :max_size =>
400) %>
  <% end -%>

Finally some CSS

.tagcloud {
  text-align: center;
  width: 70%;
.tagcloud li {
  display: inline-block;
  display: -moz-inline-box;
  white-space: nowrap;
  vertical-align: middle;
  line-height: 1.2em;
  padding: 0 0.2em;

On a self-serving note, let me point you to


Michael S.
Chris T (Guest)
on 2007-02-14 12:13
(Received via mailing list)
Mike D. wrote:
> Hi:
> Anyone know of anyone that's implemented AND made available a tag cloud
> implemented in rails?
> Thanks!
> Mike
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 =" if except.empty? &&
    conditions = ["(taggings.tag_id = AND
(taggings.taggable_type IN (?))", only.collect {|m| m.to_s.classify }]
if !only.empty? # optional
    conditions = ["(taggings.tag_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 => "",
:order => " 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 -
    output = tag_cloud.collect { |tag| link_to(,
                                                {:controller =>
'search', :tag =>},
                                                {: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.

This topic is locked and can not be replied to.