Thursday, April 13, 2006

Ruby on Rails, acts_as_taggable plugin frustration


I'd been working on a project using ruby on rails as of late. The project, like so many other recent projects involves all the "web 2.0" features such as tagging, social networking, AJAX, the list goes on.

One real advantage of using rails for such a project is their extreme willingness to support the web 2.0 features listed above, so much so that you can get most of these features for free if you're doing things right. Features they missed can be extended via two different channels: plugin system or gem package management system.

This is where things can get a little confusing. A real live example is the simple problem of tagging: there are two extensions for rails for tagging, both of which are named "acts_as_taggable". different group of people, using plugin system and gem system respectively, approaching the problem with slightly different approach.

Putting aside the problems with namespace pollution inside the framework, learning the new extension becomes extremely annoying with the search on google. A "acts_as_taggable" google gives you a mix of results with methods from both systems, and with no real way to distinctly differentiate between the two except to try the commands on the extension of your choice.

Anyways, that is not what this post's about.

I'm using "acts_as_taggable" plugin, which is great, but for whatever reason, it does not detect double entry. For example, we have objects "book" and "author", both of which are taggable. If the user tag a book as "interesting", and later did the same thing again, the tag "interesting" would be on the book's page twice.

This is a problem with the taggings table. When an object (a book) is tagged, acts_as_taggable method uses the find_or_create_by_name method to make sure that entries in the Tags table has no dulplicated entry. After this, it calls on( ) method in Tag model to link our object (the book) to our tag (the entry we just created or found, "interesting" in this case). Unfortunately there is no checking for duplicate in this step. So even though tags name in the tags table contains unique entries, same tags for the same object can appear multiple times.

To go around this problem, I replaced the following line in tag.rb in vendor/plugins/acts_as_taggable/lib/ of your application folder

taggings.create :taggable => taggable

Into this

taggings.find_or_create_by_tag_id_and_taggable_id_and_taggable_type(id, taggable.id, taggable.class.to_s);



This is meant to be a quick fix of the problem I'm having, not nearly an elegant solution. I don't know how expensive find_or_create_by method, so I have no idea if this was left out of the plugin intensionally.

3 comments:

Anonymous said...

Dude. Was looking at your flicker photos. Man, where'd you go travel? Those places look amazing, man. Real purty scenery. You go wit' yo mommy? :) Looks like you're getting to do some pretty cool stuff.

Anonymous said...

I needed this so much. Thank you.

Anonymous said...

Wow. You have no idea how great this is and how long I've been looking for it. Thank you so much!