Tagging Tutorial

Installation of “acts_as_taggable_on_steroids”

In the terminal, type the following:

 
shell> script/plugin install http://svn.viney.net.nz/things/rails/plugins/acts_as_taggable_on_steroids

+ ./acts_as_taggable_on_steroids/CHANGELOG
+ ./acts_as_taggable_on_steroids/MIT-LICENSE
+ ./acts_as_taggable_on_steroids/README
+ ./acts_as_taggable_on_steroids/Rakefile
+ ./acts_as_taggable_on_steroids/.../acts_as_taggable_migration_generator.rb
+ ./acts_as_taggable_on_steroids/.../templates/migration.rb
+ ./acts_as_taggable_on_steroids/init.rb
+ ./acts_as_taggable_on_steroids/lib/acts_as_taggable.rb
+ ./acts_as_taggable_on_steroids/lib/tag.rb
+ ./acts_as_taggable_on_steroids/lib/tag_counts_extension.rb
+ ./acts_as_taggable_on_steroids/lib/tag_list.rb
+ ./acts_as_taggable_on_steroids/lib/tagging.rb
+ ./acts_as_taggable_on_steroids/lib/tags_helper.rb
.
.
.

Usage

Migration

Generate migration

  • “ruby script/generate acts_as_taggable_migration” is a method that creates the tables tags and taggings.
  • Taggings is a table that allows polymorphic associations, creating “has_and_belongs_to_many” relationships between all the tables.
ruby script/generate acts_as_taggable_migration

To apply the migration:

rake db:migrate

Model

Let’s suppose there is a model called Grant and we want all of our categories (i.e. grants) to both have multiple tags, and have our tags be applied to multiple categories. The first step is to add acts_as_taggable to your model:

class Grant < ActiveRecord::Base

   acts_as_taggable

end

We can now use the tagging methods provided by acts_as_taggable, “tag_list” and "tag_list = ".

Controller

Place the following code in your controller where you wish to have tags

  • For example, differentiating between pages to edit existing grants versus pages to create new grants.
p = Grant.find(:first)

To find objects that have been tagged, use find_tagged_with. Here, you are defining the “tag” method within the grants controller.

def tag
  @grants = Grant.find_tagged_with params[:id]
end

Views

To display tags associated with the specific grant, add a place to show tags on views/grant/show.rhtml

<p>Tags:</p>
<p><%= @grant.tags.collect {|t| t.name }.join(", ") %> </p>

In order to edit or add tags to your form, you need a field. This is how it would look:

<%= text_field :grant, :tag_list %> * separated with commas

To show a list of grants tagged with that word, create a new rhtml file “tag.rhtml” in Views. The code is pretty similar to that of index.rhtml, except the title of the page will include the name of the tag and

<h2>Grants tagged with <%= params[:tag] %></h2>

<ul>
  <% @grants.each do |grant| %>
    <li><%= link_to grant.title, 
            :action => 'show', :id => grant.id  %></li>
  <% end %>
</ul>

To create tagging clouds, create the new partial tags.rhtml in apps/views/home/tags.rhtml.

This should relate the tag name to grants that are tagged with that word. It must call on the grants_controller in this instance, then find the tag name based upon the ID of the grants.

The <% tag_cloud Grant.tag_counts, %w(css1 css2 css3 css4) do |tag, css_class| %> part is so that the text of the tags on the index page will be bigger or smaller depending on the number of grants that the tag is attributed to (the more the tag is applied, the bigger the text will be).

<% tag_cloud Grant.tag_counts, %w(css1 css2 css3 css4) do |tag, css_class| %>
  <%= link_to tag.name, { :controller => 'grants', :action => :tag, :id => tag.name }, :class => css_class %>
<% end %>

To show list of tags next to the name of the grants, include in the grants_helper.rb a calling of the helper “grant_tag_links(grant)” to place where grants are listed.

  • (grant) is named in calling of the helper to pass that argument from the view to the helper.
<%= grant_tag_links(grant) %>

(see Helpers section below)

Helpers

Create a helper within grants_helper.rb that will retrieve the list of associated tags with each grant, list them (separated by commas), and be active links to show other grants associated with that tag.

  def grant_tag_links(grant)
    return "" unless grant.tag_list.any?
    tag_links = grant.tag_list.collect do |tag|
      link_to tag, :controller => 'grants', :action => 'tag', :id => tag
    end
    tag_string = tag_link.join(', ')
    "(" + tag_string + ")" 
  end

Helpful Links

 

this line:

“ruby script/generate acts_as_taggable_migration” creates a “has_many” relationship between tag IDs and grant IDs.

is not technically true. it create a polymorphic association between tags and anything (tag belongs_to the other thing)

 
 

You should separate this tutorial into 3 parts that corresponds to MODEL, VIEW, CONTROLLER. This will make it more clear in terms of where changes need to happen and what effects they will have.

 
   

I implemented the tagging plugin, and I’ve got some questions.

1) Of course, when I try to visit the website, I get an error. I don’t even know how to begin to fix this. So… What are some good methods for troubleshooting?

2) Is there a way to add a list of possible tags before any “Tikis” have been added? It seems like a good idea to be able to have a few broad subject groups (like “Politics”, “Global Warming”, etc.).