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.
This is a copy/paste from my question over at StackOverflow so 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?
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?