Open-source Rails migration tool

Migration Data: keep your data migrations working as your app evolves

A migration can change records as well as tables. But the models it calls keep evolving. Migration Data gives that record-changing code a dedicated hook you can test before it runs against production data.

MIT-licensed gem · Data hooks within Rails migrations

Migration DataChange the schema. Test the data
  1. 01
    Define the schema changeUse the usual change or up method for tables and columns.
  2. 02
    Put record updates in dataKeep the backfill in a method your tests can call directly.
  3. 03
    Test, then migrateAssert the intended record changes. Run rails db:migrate to apply the schema and execute the data hook.

Tests check the behavior you specify. Review the migration against your application and production data before deploying.

Start with your existing workflow

Install once. Keep using Rails migrations

Add migration_data to your application's Gemfile and install it. Include it in the environments that run your migrations.

Define a data method in a migration. The gem runs it after the usual schema operation when migrating up.

# Gemfile
gem 'migration_data'

# Terminal
bundle install
rails db:migrate
Read installation and usage details

Published on RubyGems

A tool developers keep downloading

View migration_data on RubyGems →
Total downloads
3.26M
Published version
0.6.0
License
MIT

RubyGems snapshot, October 13, 2026: 3,260,281 downloads. Counts include repeat downloads and do not represent unique users or active installations.

From the project community

What developers are saying

Public feedback from migration_data users and contributors on GitHub. Each quote links to the original discussion.

The gem is also listed in Made in Belarus →, a collection of open-source projects made in Belarus.

User feedback · GitHub

I just used this gem with Rails 7.0.4 and minitest and it works fine, found it quite useful.

KjellMorgenstern →Reported use with Rails 7.0.4 and Minitest

User feedback · GitHub

Hi, thanks for developing the awesome gem!

fursich →Opening excerpt from a column-cache issue report

Contributor feedback · GitHub

Thanks @ka8725. Awesome work! Just arrived home and seeing this now

mapreal19 →Comment in a contribution discussion

The problem behind the gem

Yesterday's migration. Today's models

A migration may work when you write it and fail later when a model is renamed, validation changes, or an association behaves differently. Testing the data logic makes those dependencies visible.

01

Separate the responsibilities

Put schema operations in the standard Rails methods and record changes in data hooks within the same migration.

02

Check the intended outcome

Assert what changed in the records, not just that the method ran without raising an exception.

03

Catch regressions in CI

Run migration tests as the application evolves, so changes to models can expose broken data logic before deployment.

A practical example

Add a column, then backfill existing users

This migration adds a string column and sets every existing user's status to pending. The data hook runs after change.

reset_column_information refreshes the model's column information before the update. This example uses a Rails 6.0 migration class; use the migration version appropriate for your application.

class AddStatusToUsers < ActiveRecord::Migration[6.0]
  def change
    add_column :users, :status, :string
  end

  def data
    User.reset_column_information
    User.update_all(status: 'pending')
  end
end

Small hooks. Useful control

Built around testable data changes

Data logic you can test

Give record updates their own data method. Exercise it directly in your test suite and check the resulting records, so model changes do not quietly break an old backfill.

A familiar migration workflow

Run the usual Rails migration task. The gem invokes the data hook after the schema change, keeping related schema and record changes together in one migration file.

Control the execution order

Use data_before when records need changing before a schema operation. The data and data_after hooks run afterward. Choose the order that fits the change.

Explicit rollback hooks

Define rollback_before, rollback, or rollback_after when a data change needs its own reversal. Write and test the reverse operation yourself; the gem does not infer it.

Load migrations in your tests

Require migration_data/testing and use require_migration to load a migration by name. Keep focused tests alongside the rest of your Rails test suite.

Optional environment configuration

MigrationData.config.skip can disable data hooks in an environment where they should not run. Keep that choice explicit, especially when test setup already supplies the data.

Make the behavior explicit

Test the backfill directly

Load the migration with require_migration, create a user with no status, and call the data method. Then assert that the user received the expected value.

This RSpec example assumes FactoryBot is configured and the test database already has the status column. It tests the record update separately from the schema operation.

Explore the testing helper →
require 'rails_helper'
require 'migration_data/testing'
require_migration 'add_status_to_users'

RSpec.describe AddStatusToUsers do
  describe '#data' do
    it 'backfills existing users' do
      user = create(:user, status: nil)

      described_class.new.data

      expect(user.reload.status).to eq('pending')
    end
  end
end

Know what the hooks do

Plan the rollback and the workload

On rollback, the schema operation runs before rollback and rollback_after. Use rollback_before if the reverse data operation needs a column that the schema rollback removes.

The gem organizes execution. You still decide how to reverse data changes and whether a large backfill needs batching or a separate deployment step.

Engineering knowledge, shared

01

Change data in migrations like a boss

Andrei's article explains the approaches that led to migration_data and why tests matter for migration code.

Read the original article →
02

Keep your local schema aligned

Actual DB Schema addresses another migration problem: database state left behind when you switch Git branches.

Explore Actual DB Schema →
03

Contribute to the project

Read the source, report an issue, or propose an improvement to migration_data.

Visit GitHub →

Built by WideFix founder Andrei Kaleshka

Need help changing a live Rails application?

We maintain existing Rails applications, plan upgrades, and deliver production data changes. That hands-on work shapes the open-source tools we share with the community.

Explore our Rails maintenance services
Back to TopBack to Top