for purpose of reference: enable tagging in a Rails model
As my yesterday posting on how to do many-to-many relationships in Rails turned out to be popular, today I give an example for how to add tags to a Rails model in the same stripped down style.
Just like yesterday, as the thing that shall get tags attached we want an item model. And we want to make use of the tagging tool.
To achieve the little today goal, we need a scaffold for the item model first, then install a plug-in for the tagging, do some modification to the model, views, and the plug-in itself. To the plug-in only because this little project aims for quick results — to get the matter clear —, not for comfort.
To prevent possible side-effects with whatever project we might be working on already, let’s start a completely new project:
$ rails tag_me && cd tag_me
... [output] ...
Then the let’s apply scaffold to get the model set up:
$ ./script/generate scaffold item name:string && rake db:migrate
... [output] ...
Now we install the plug-in for the tagging:
$ ruby script/plugin install http://svn.viney.net.nz/things/rails/plugins/acts_as_taggable_on_steroids
... [output] ...
(I used acts_as_taggable_on_steroids because the plug-in it’s based upon, acts_as_taggable, looks outdatedly.)
$ ruby script/generate acts_as_taggable_migration && rake db:migrate
... [output] ...
Once done with that, we have everything in place to perform the necessary modifications on both, the plug-in and the scaffolded application. Since everything depends on the plug-in, we start our modifications there:
file: vendor/plugins/acts_as_taggable_on_steroids/lib/acts_as_taggable.rb:
At the end of the module body (currently line 200) we insert two additional methods:
def tags_as_text tag_list end def tags_as_text= text self.tag_list = text end
Next, we make the item taggable, by inserting a acts_as_taggable into the class body:
file: app/models/item.rb:
class Item < ActiveRecord::Base acts_as_taggable end
(Bold code lines like the one above are those you need to insert.)
That’s it, mainly. What’s left is to update the views so that tags get displayed and can get entered:
file: app/views/items/index.html.erb:
<h1>Listing items</h1>
<table>
<tr>
<th>Name</th>
<th>Tags</th>
</tr>
<% for item in @items %>
<tr>
<td><%=h item.name %></td>
<td><%=h item.tags_as_text %></td>
<td><%= link_to 'Show', item %></td>
<td><%= link_to 'Edit', edit_item_path(item) %></td>
<td><%= link_to 'Destroy', item, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>
</table>
<br />
<%= link_to 'New item', new_item_path %>
file: app/views/items/new.html.erb:
<h1>New item</h1>
<%= error_messages_for :item %>
<% form_for(@item) do |f| %>
<p>
<b>Name</b><br />
<%= f.text_field :name %>
</p>
<p>
<b>Tags</b><br />
<%= f.text_area('tags_as_text') %>
</p>
<p>
<%= f.submit "Create" %>
</p>
<% end %>
<%= link_to 'Back', items_path %>
file: app/views/items/show.html.erb:
<p> <b>Name:</b> <%=h @item.name %> </p> <p> <b>Tags</b><br /> <%= @item.tags_as_text %> </p> <%= link_to 'Edit', edit_item_path(@item) %> | <%= link_to 'Back', items_path %>
file: app/views/items/edit.html.erb:
<h1>Editing item</h1>
<%= error_messages_for :item %>
<% form_for(@item) do |f| %>
<p>
<b>Name</b><br />
<%= f.text_field :name %>
</p>
<p>
<b>Tags</b><br />
<%= f.text_area('tags_as_text') %>
</p>
<p>
<%= f.submit "Update" %>
</p>
<% end %>
<%= link_to 'Show', @item %> |
<%= link_to 'Back', items_path %>
Now you can launch the server by the common
$ ./script/server
and direct your browser to
There you can enter some dummy data (using the ‘new item’ link).
Notes:
- Despite single quotes in this posting get displayed as oblique ‘…’, in the source code you need real single quotes. — If you just copypaste the source and keep the wry single quotes, things might go wrong.
- To separate several tags from each other you can utilize te comma (,) character. Multiple identical tags get treated as a single one.
- To develop the above intro, I made use of the acts_as_taggable_on_steroids page and Simple Tag IO with acts_as_taggable_on_steroids.
- While aiming at getting a clue of how to deal with tags in Rails at all, I also found these sources useful: Installing the acts_as_taggable Rails Plugin and growing up your acts_as_taggable.
- In the neighbourhood of my search for/on how to deal with acts_as_taggable.*, I found some promising drill-ups related to acts_as_taggable.* such as auto-completion for acts_as_taggable_on_steroids by Ariejan de Vroom, acts_as_taggable per user tagging by Ben Smith (and some hiccup fixing on that by Micah Wedemeyer/Ryan Felton), Creating a TagApplicator for acts_as_taggable by Bryan Ray and Extending acts_as_taggable to take scope into account (by unknown, found on DZone).
Update: I got aware of some more act_as_taggable* resources, e.g. acts_as_taggable_on by intridea or those found on github (via Bryan Ray). - Last not least, I stumbled upon a tutorial on writing plug-ins for Rails. Might be useful, but I didn’t try it yet.
Great tutorial, clear and precise!
pragmatig
June 20, 2008
Good write up.
Thanks for the link.
Bryan Ray
June 23, 2008
Just what I was looking for
ink
August 15, 2008
hi your plugin is so nice and i installed it
and everything working fine and how to do
validations for this please help me from this
suresh
January 20, 2009
@suresh I’m off Ruby since a while now.
Please note: The plug-in is not mine. I recommend you ask the original author for specific questions about is code.
On unrelated technical support questions or “make my homework, nanny” questions, please note: Google is your friend.
dagobart
January 21, 2009