Rails Migrations to Add a Column and Change Column Type

Suppose we have a Post model with body:integer and title:string columns. Generate a migration to add a user_id column to the posts table.

$ rails g migration AddUserIdToPosts

Update the migration file, so the $ rake db:migrate command will add the user_id column to the posts table.

class AddUserIdToPosts < ActiveRecord::Migration
  def change
    add_column :posts, :user_id, :integer
  end
end

The change method automatically lets us run the migration and roll it back, so all of the following commands will execute as expected:

$ rake db:migrate
$ rake db:rollback
$ rake db:migrate

Lets add another migration to change the type of the body column to be text instead of an integer.

$ rails g migration ChangeBodyTypeInPosts
class ChangeBodyTypeInPosts < ActiveRecord::Migration
  def change
    change_column :posts, :body, :text
  end
end

If we run this migration and check the schema file, we will see that it was successful in changing the type of the body column to text. However, this migration is flawed because a rollback is not allowed:

$ rake db:rollback
==  ChangeBodyTypeInPosts: reverting ==========================================
rake aborted!
An error has occurred, this and all later migrations canceled:

ActiveRecord::IrreversibleMigration
Tasks: TOP => db:rollback
(See full trace by running task with --trace)

Some migrations are meant to raise an ActiveRecord::IrreversibleMigration exception, but this is the type of migration where that is probably not true. Here is a better way to create the migration:

class ChangeBodyTypeInPosts < ActiveRecord::Migration
  def self.up
    change_column :posts, :body, :text
  end

  def self.down
    change_column :posts, :body, :integer
  end
end

When the up and down methods are specifically defined, migrations and rollbacks both function properly. This leads to a more general point: whenever you create a migration, check to make sure it can be rolled back and migrated successfully.

Advertisements

5 thoughts on “Rails Migrations to Add a Column and Change Column Type

  1. I just started and tried to create a Post model that has a body column. I ran rails g model Post body:text but this doesnt seem to be right.

    • That should work. You might have forgotten to create your database. If you’re still having problems, post your question / errors on StackOverflow, send me a link to the StackOverflow post, and I’ll make sure to take a look. Thanks!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s