oma oma - 6 months ago 49
Ruby Question

Migrating DATA - not just schema, Rails

Sometimes, data migrations are required. As time passes, code changes and migrations using your domain model are no longer valid and migrations fail. What are the best practices for migrating data?

I tried make an example to clarify the problem:

Consider this. You have a migration

class ChangeFromPartnerAppliedToAppliedAt < ActiveRecord::Migration
def up
User.all.each do |user|
user.applied_at = user.partner_application_at

this runs perfectly fine, of course. Later, you need a schema change

class AddAcceptanceConfirmedAt < ActiveRecord::Migration
def change
add_column :users, :acceptance_confirmed_at, :datetime

class User < ActiveRecord::Base
before_save :do_something_with_acceptance_confirmed_at

For you, no problem. It runs perfectly. But if your coworker pulls both these today, not having run the first migration yet, he'll get this error on running the first migration:

rake aborted!
An error has occurred, this and all later migrations canceled:
undefined method `acceptance_confirmed_at=' for #<User:0x007f85902346d8>

That's not being a team player, he'll be fixing the bug you introduced. What should you have done?


Best practice is: don't use models in migrations. Migrations change the way AR maps, so do not use them at all. Do it all with SQL. This way it will always work.


User.all.each do |user|
  user.applied_at = user.partner_application_at

I would do like this

update "UPDATE users SET applied_at=partner_application_at"