Garbage Burrito

Rails: Data Migrations

Rails: Data Migrations
Ben Kittrell - 08/14/2006 13:00:00
Comments: 5
Last Comment: 07/07/2009 15:44:12

I needed to add the tinyMCE WYSIWYG editor to my blog editor for obvious reasons. Previously I was using simple_format to add formatting tags post db. So now that the HTML was going to be stored in the database, I needed to retroactively format the old posts with HTML. A simple process, but how was I actually going to facilitate this? A database script? A ruby process? After working in Rails I don't like these decisions, it seems like there should be something for me to use already. Thankfully there is.

Hopefully all you Railers have heard of and are currently using migrations. They're a handy little tool for managing your database schema, and makes updating production systems a snap. For more info check out the Wiki page or DHH's slick migration demo. Up till now I had only used migrations for modifying tables, but why can't they be used for data migration? Here's an example.

class AutoFormatBlog < ActiveRecord::Migration
  extend ActionView::Helpers::TextHelper
  extend ActionView::Helpers::TagHelper

  def self.up
    entries = Entry.find(:all)
    for entry in entries
      entry.content = simple_format(entry.content)
      entry.save
    end
  end

  def self.down
    entries = Entry.find(:all)
    for entry in entries
      entry.content = strip_tags(entry.content)
      entry.save
    end
  end
end

As you can see this is very simple. The 'up' method simply iterates through all of the blog entries and uses simple_format to add HTML tags. The 'down' method is used to undo this by calling strip_tags. This is one of the major benefits of using migrations is that you can write and test your 'undo' ahead of time.

So you get a standardized method of migrating data, built-in undo, and access to active record and other ruby goodies.

Comments: 5
Last Comment: 07/07/2009 15:44:12

Comments

1. rheaghen   |   08/17/2006 07:40:53

sounds highly useful! I admire your courage and pioneering spirit!

2. Lan Wirelles  |  my website   |   05/23/2008 12:51:21

the code is correct !

3. impresora  |  my website   |   05/27/2008 22:32:40

very cool

4. Peter   |   04/08/2009 11:59:46

I like the idea, but what happens if someone commits a removal/rename on the Entry model? Then self.down crashes (self.up too for that matter), right?

You could avoid crashing by checking that Entry exists first, or putting this in a begin/rescue (perhaps raising a rollback exception within rescue, if you have migration transactions activated). But then you can't rely on your data migration working in the future, so maybe better log some warnings in rescue too. Or else just mark this an irreversible migration?

5. Mark   |   07/07/2009 15:44:12

Have to agree wtih Peter here. Data migrations actually need a separate mechanism.
I think data migrations need to actually be in the model or in something closely related to the model so that if the model is altered or modified, it can be changed.

Data migrations do need a similar versioning, though, because you wouldn't want to run them more than once.

I'm noticing this in my 2 year old rails project. I can't run db:migration from a clean db because so many of the older models are already altered or renamed.

Post a Comment


Are you human? Please enter the word below.
M2zhcmnllmpwzzeynjkxmzk0mzi=


powered by Doodlekit™ Free Website Builder by Doodlebit™ Website Company