Going from acts_as_taggable_on_steroids to acts_as_taggable_on Plugin
Posted by g. | Filed under Ruby on Rails
For one reason or another, once I upgraded my app to Rails 2.1, I started getting these mysterious “stack level too deep” errors. I’m not too sure what that even means, but I won’t get into it here. After diving into the stack trace for a little while, I noticed that the problem was with the acts_as_taggable_on_steroids plugin (for whatever reason). It turns out this plugin isn’t even being maintained anymore (I may be wrong on that, but I read it in a few places).
In comes the improved acts_as_taggable_on plugin. In addition to being compatible with Rails 2.1, it has a few more really cool features like having different “categories” or “sets” of tags. I’ll leave you to read all about it here.
But if you’re like me, you already have all sorts of tags and taggings in your existing database, and you REALLY don’t want to wipe all your data and run the acts_as_taggable_on migration from scratch. I found a blog post that got me started on the migration process, but it had a few errors and was incomplete, hence my reason for writing this.
Luckily the database structure between AATOS and AATO is very similar. We’ll get to that in a second. First, you’ll want to install AATO like normal (again, refer to this link).
Note: I was doing this on a Windows machine, and I needed to install git before I could run the script/plugin install git://github.com/mbleigh/acts-as-taggable-on.git. I got it from http://code.google.com/p/msysgit/downloads/list, and at the time of writing the version I installed was Git-1.5.6.1-preview20080701.exe.
Next, you’ll want to generate your migration file, exactly like you did back in the day (which was a Wednesday by the way) when you installed AATOS. So, script/generate acts_as_taggable_on_migration. If you didn’t previously use any tagging plugin, running rake db:migrate now would create two new tables, tags and taggings. But you already have those two tables! So running that migration as is would probably cause all sorts of a mess. What we want to do is edit the migration file to ALTER your existing tables, thus keeping all your precious existing tags around and working.
Note: If you’re committed to doing this upgrade, it is safe to delete your acts_as_taggable_on_steroids folder found in vendor/plugins.
So, we shall change the migration to look like this (read my code comments to understand what’s going on):
class ActsAsTaggableOnMigration < ActiveRecord::Migration def self.up # this has been modified to upgrade the tables previously created by acts_as_taggable_on_steroids # get rid of the old table index in the taggings table remove_index :taggings, [:taggable_id,:taggable_type] # these are the three new columns necessary for the new plugin to work add_column :taggings, :tagger_id, :integer add_column :taggings, :tagger_type, :string add_column :taggings, :context, :string # these are the two new indexes necessary for the new plugin to work add_index :taggings, :tag_id add_index :taggings, [:taggable_id, :taggable_type, :context] end def self.down drop_table :taggings drop_table :tags end end
Now, run that migration with rake db:migrate. We still need to make a few changes. Go to your model(s) which actually have tags. Previously you declared something like acts_as_taggable in each of them. You’ll need to change this to specify the tag “category” or “set” like we previously mentioned. So change that acts_as_taggable line to read acts_as_taggable_on :tags. You can put whatever you want in the place of :tags, but I’m just making it generic.
One more step is necessary to get your existing tags working again. In your database, your taggings table now has 3 new columns (all three should be empty). You need to fill in the :context column with the value “tags”, which is what I arbitrarily showed above. If you chose to say acts_as_taggable_on :interests, then the context column needs to be populated with “interests”. That should do it!
Tags: acts_as_taggable_on, acts_as_taggable_on_steroids, migrate, plugins, Rails 2.1
4 Responses to “Going from acts_as_taggable_on_steroids to acts_as_taggable_on Plugin”
-
Blake Miller Says:
March 12th, 2009 at 4:53 pmThanks for doing this!
I altered the ‘down’ method in the migration thusly, so it doesn’t delete tags/taggings but alters them back to the way they were:
class ActsAsTaggableOnMigration [:taggable_id, :taggable_type, :context]
remove_index :taggings, :column => :tag_idremove_column :taggings, :context
remove_column :taggings, :tagger_type
remove_column :taggings, :tagger_idadd_index :taggings, [:taggable_id,:taggable_type]
end
end
-
Blake Miller Says:
March 12th, 2009 at 4:55 pmignore previous post please, here is the code I was talking about:
def self.down
remove_index :taggings, :column => [:taggable_id, :taggable_type, :context]
remove_index :taggings, :column => :tag_idremove_column :taggings, :context
remove_column :taggings, :tagger_type
remove_column :taggings, :tagger_idadd_index :taggings, [:taggable_id,:taggable_type]
end -
g. Says:
March 12th, 2009 at 5:16 pm@Blake Miller thanks, good thing to add!
-
Dwayne Says:
April 11th, 2009 at 6:42 pmGreate post!!!!
I did a slight modification. Same as above for down method but I also added the following to the up methodFor those who will keep tags as tags:
execute(”UPDATE taggings SET context = ‘tags’”)