Skip to content

Instantly share code, notes, and snippets.

@tuzz
Created August 3, 2012 16:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tuzz/3249000 to your computer and use it in GitHub Desktop.
Save tuzz/3249000 to your computer and use it in GitHub Desktop.
A fairly comprehensive acts-as-taggable-on tag migrator.
class TagMigrator
class << self
def list_tags(search_term = nil)
puts Tag.where('name like ?', "%#{search_term}%").order(:name).map(&:name)
end
def migrate!(old_name, new_name)
if old_name.downcase == new_name.downcase
rename!(old_name, new_name)
return
end
old_tag = Tag.find_by_name!(old_name)
new_tag = Tag.find_or_create_by_name(new_name)
execute("update taggings set tag_id = #{new_tag.id} where tag_id = #{old_tag.id}")
old_tag.destroy
end
def rename!(old_name, new_name)
raise_if_about_to_clobber_another_tag(old_name, new_name)
tag = Tag.find_by_name!(old_name)
tag.update_column(:name, new_name)
end
def remove!(tag_name)
tag_to_remove = Tag.where(:name => tag_name).first
execute("delete from taggings where tag_id = #{tag_to_remove.id}")
tag_to_remove.destroy
end
private
def execute(sql)
ActiveRecord::Base.connection.execute(sql)
end
def raise_if_about_to_clobber_another_tag(old_name, new_name)
if (t = Tag.find_by_name(new_name)) && t.name.downcase != old_name.downcase
raise MigrationError.new('Cannot rename to a tag that already exists. Use migrate! instead.')
end
end
class ::MigrationError < StandardError; end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment