Doing freelance with Rails, I keep facing an issue when I join an existing project: outdated migrations that fail dozens of times during
To fix those, I need to do very hacky things, like commenting the failing lines, but also the already-migrated-schema ones which is very error-prone. Anyways, that’s not the way it should be.
Should I use
? That’s not what I read as a good practice.
After some thinking, I came up with the simple idea of separating schema migrations from data migrations.
Because it’s always data migration that fail.
class AddStatusToUser < ActiveRecord::Migration def up add_column :users, :status, :string User.find_each do |user| user.status = 'active' user.save! end end def down remove_column :users, :status end end
Then you’d remove the
User class and the migration is broken.
After some search, I found this very nice article that summarized all the pain-points coming from not separating data migrations and schema migrations : http://railsguides.net/change-data-in-migrations-like-a-boss
Here, Andrey Koleshko suggests the following syntax:
class CreateUsers < ActiveRecord::Migration
# Database schema changes as usual
I would suggest instead, something like creating two types of migrations : normal migrations, that remain unchanged, and data migrations, that would work the following way:
class CreateDefaultUser < ActiveRecord::DataMigration # Inherits from a different class: DataMigration
I reckon it makes sense to put it in different files, as this is not the same type of database modification. And would be created calling rails generate migration --data CreateDefaultUser `` They would behave slightly differently: - Ignored when running something like: rake db:migrate --no-data # or rake db:setup --migrations `` `` - or at least non-blocking (rescuing exception as a warning) The cool thing about this is that there is no backward compability issue here. You could say that's ok, there's already a gem that does that, those who need it can use it. But that's not true, as most developers would find out about the gem way too late, when all their broken migrations are already there. Plus if we call it a "best practice", it should not be optionnal. If it does make sense, I would definitely look at how to write such change. Thanks for consideration.