Ruby on Rails
Database Migration
Rename Column
Programming
Web Development

How can I rename a database column in a Ruby on Rails migration?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Renaming a column in Rails is simple at the API level, but the migration is only one part of the change. You also need to think about application code, indexes, constraints, and deployment order. The safe answer is rename_column, followed by a careful sweep of everything that still references the old name.

The Basic Migration

Rails provides rename_column for this exact operation. The migration takes a table name, the current column name, and the new column name.

ruby
1class RenameEmailToEmailAddressInUsers < ActiveRecord::Migration[7.1]
2  def change
3    rename_column :users, :email, :email_address
4  end
5end

Generate the migration with a descriptive name:

bash
bin/rails generate migration RenameEmailToEmailAddressInUsers
bin/rails db:migrate

For many databases, Rails can reverse this migration automatically when you run db:rollback, because the framework knows the old and new names.

What the Migration Changes

At the database level, a rename changes the column identifier, not the data itself. Existing values remain in place. That makes renaming much cheaper than creating a new column, copying data, and dropping the old one.

For example, if the users table contains:

text
id | email
1  | [email protected]
2  | [email protected]

after the rename it becomes:

text
id | email_address
1  | [email protected]
2  | [email protected]

The records are unchanged. Only the column name exposed to SQL and Active Record has moved.

Updating the Application Code

The migration is the easy part. The bigger risk is forgetting references in the codebase. After renaming email to email_address, all of these must be checked:

  • model validations
  • controllers and strong parameters
  • views and form builders
  • serializers
  • background jobs
  • raw SQL fragments
  • tests and fixtures

For example, this form must change:

erb
1<%= form_with model: @user do |form| %>
2  <%= form.label :email_address %>
3  <%= form.text_field :email_address %>
4<% end %>

And controller whitelisting must change too:

ruby
def user_params
  params.require(:user).permit(:email_address, :name)
end

If even one part of the application still calls user.email, you will get runtime failures after the migration is applied.

When You Need a Safer Multi-Step Deployment

For small apps or a local project, a direct rename is usually fine. In a production system with rolling deploys, a column rename can break old application instances that are still running while the new migration has already been applied.

In that case, a safer deployment is often:

  1. add a new column
  2. write to both columns temporarily
  3. backfill old data
  4. switch reads to the new column
  5. remove the old column later

That is more work, but it avoids a deploy window where old code expects email and new schema exposes only email_address.

Use a direct rename when:

  • the app is small
  • deploy and migration happen in lockstep
  • there are no old workers or web nodes running during rollout

Use a multi-step migration when:

  • zero-downtime deploys matter
  • multiple app versions may run at once
  • external consumers depend on the old schema

Renaming Indexes and Constraints

The column rename does not guarantee every related database object gets a clean new name. The database may continue to use an index name that still contains the old column label.

For example, after renaming a column, you might also want:

ruby
1class RenameUserEmailIndex < ActiveRecord::Migration[7.1]
2  def change
3    rename_index :users, :index_users_on_email, :index_users_on_email_address
4  end
5end

Whether this is necessary depends on your schema and database adapter, but it is worth checking the generated schema file or the database itself after migration.

If you use raw SQL constraints, views, triggers, or stored procedures, Rails will not automatically rewrite those for you. Those dependencies need a separate review.

Verifying the Result

After migration, confirm both the schema and the app behavior.

bash
bin/rails db:migrate
bin/rails console

Then in the console:

ruby
User.column_names.include?("email_address")
user = User.first
puts user.email_address

Also run the relevant test suite. Column renames often surface hidden coupling in factories, request specs, and admin code.

Common Pitfalls

  • Renaming the column in the database but not in the Rails code. Search the codebase for the old name before and after migration.
  • Assuming a direct rename is always safe in production. Rolling deploys can break when old code and new schema overlap.
  • Forgetting related index names or raw SQL references. Review schema details beyond the model file.
  • Using rename_column when the change also needs a type conversion. In that case, a multi-step migration is usually clearer.
  • Running the migration without test coverage for forms, APIs, and background jobs that touch the renamed attribute.

Summary

  • Use rename_column :table, :old_name, :new_name for the basic Rails migration.
  • The data stays in place; only the identifier changes.
  • Update every application reference to the old column name.
  • Consider a multi-step rollout when zero-downtime deployment matters.
  • Check indexes, raw SQL, and tests after the rename, not just the migration file itself.

Course illustration
Course illustration

All Rights Reserved.