Friday, March 03, 2006

Tagging on Rails: acts_as_taggable count DESC

Today, while working on a project involving acts_as_taggable I noticed something interesting:

I was using something like:

@tagged_blogosphere = Webpage.tags_count(:limit => 100,:order=>' count desc ' )



and this was producing the following SQL statemetn:

SELECT tags.id AS id, tags.name AS name, COUNT(*) AS count FROM tags_webpages, webpages, tags WHERE tags_webpages.tag_id = tags.id
AND tags_webpages.webpage_id = webpages.id GROUP BY tags.name ORDER BY count desc LIMIT 100



However, the records weren't really in order specified.

After a few minutes of researching I found that the order is lost when the hash is being prepared for the tags_count table.

So, following the advice mentioned on Singleton methods for acts_as_taggable page, I modified my call as follows

@tagged_blogosphere = Webpage.tags_count(:limit => 900,:raw=>true, :order=>' count desc ' )



Because of that, I had to change my display also (thanks to Tom Fakes for the tag cloud function.

<ul class="taglistinline">
<% tag_cloud(@tagged_blogosphere, %w(cloud1 cloud2 cloud3 cloud4 cloud5 cloud6 cloud7)) do |tag, cloud_class| %>
<!-- < %= link_to(h("<#{tag}>"), tag_item_url(:name => tag), { :class => cloud_class } ) -% > -->
<!-- <font style="font-size:<%= cloud_class %>"><%= tag%></font> -->

<li> <%= link_to(h("#{tag}"), "//#{url_home}/tag/"+ u("#{tag}"), { :class => cloud_class } ) %></li>


<% end %>
</ul>




The default implementation of Tom Fakes' function is (WHEN NOT USING :raw=>true) :

def tag_cloud(tag_cloud, category_list)
max, min = 0, 0
tag_cloud.each_value do |count|
max = count if count > max
min = count if count < min
end

divisor = ((max - min) / category_list.size) + 1

tag_cloud.each do |tag, count|
yield tag, category_list[(count - min) / divisor]
end
end



If you want to use :raw=>true option, you can use the following:


def tag_cloud_raw(tag_cloud, category_list)
max, min = 0, 0
tag_cloud.each do |element|
count = element['count'].to_i
max = count if count > max
min = count if count < min
end

divisor = ((max - min) / category_list.size) + 1

tag_cloud.each do |element|
tag = element['name']
count = element['count'].to_i
yield tag, category_list[(count - min) / divisor]
end
end

0 Comments:

Post a Comment

<< Home

eXTReMe Tracker