Implementing a tagging system in Rails

This is a copy/paste from my question over at
StackOverflowhttp://stackoverflow.com/questions/5750963/implementing-a-tagging-system-in-railsso
feel free to answer there if you want some reputation.

I’m trying to implement a tagging system in a Rails app similar to the
one
StackOverflow uses (where users enter in tags in a freeform textbox).
I’m
aware that there are gems that can do this, but I wanted to try to
implement
it myself for the learning experience. I got it to work, but since I’m a
Rails newbie I’m concerned I’m not doing it the “right way”.

Here’s my current implementation:

def Post
attr_accessor :tag_names

has_and_belongs_to_many :tags

after_save :update_tags

private
def update_tags
tags.delete_all

  if tag_names.to_s == ''
    return
  end

  tag_names.split(/,/).each do |tag_name|
    tag_name.strip!
    tag = Tag.find_or_create_by_name(tag_name)

    if !tags.exists?(tag.id)
      tags << tag
    end
  end
end

end

This makes it easy for me to set up the tags for a post since all I have
to
do is set the “tag_names” attribute on my post object. When I save the
post
object, the after_save event fires and executes my update_tags function
which then handles creating tags and linking the post to them.

Are there any problems with my implementation?

On Fri, Apr 22, 2011 at 8:09 AM, Kevin P. [email protected] wrote:

def Post
if tag_names.to_s == ‘’
end

You’re deleting the tag records on every save. So other posts which
belong
to the tags you deleted would
most probably throw an error when you try to access the tags (or will
they
silently update the the post’s tags?).

Anyway, you need to have access to the join table and delete the records
created there instead of deleting
the tag records when updating the post record.

I don’t know if it would improve performance, but instead of deleting
all
tags of the post, why not compare the
post’s current tags first and create/associate a tag to the post if it’s
not
yet associated?


You received this message because you are subscribed to the Google G.
“Ruby on Rails: Talk” group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.

I don’t think this is true. According to the Rails
APIhttp://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#M000645,
this is what collection.delete does with a has_and_belongs_to_many
association:

“Removes one or more objects from the collection by removing their
associations from the join table. This does not destroy the objects.”

I went ahead and tested this out just to make sure and sure enough, only
the
association was deleted when I called save, not the tag itself.

Just to be sure though, I’ve changed that line to be:

tags.clear

This seems cleaner anyways, and the Rails API explicitly states that
calling
this will not delete the objects themselves, only the association.

On Fri, Apr 22, 2011 at 10:20 PM, Kevin P. [email protected] wrote:

Just to be sure though, I’ve changed that line to be:

tags.clear

this sure make things clearer. i should’ve checked the api before i
commented.

For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs