If you’re using Rails engines to break up your app and you’re putting your migrations in the engines, then you’re already doing great! Here’s an additional pro-tip when it comes to having migrations within your engines: only allow each migration to touch one db table.
Why would we do this? When it comes to refactoring, there are times when you want to move a database table from one engine to another. Better yet, pull a whole table out into it’s own new engine! Or maybe you have a big Rails app, and you’re wanting to pull chunks of functionality into engines.
Doing any of these refactorings is tricky if your migrations touch multiple database tables. If you’re in this boat, then your best bet is to drop the table in one migration, and do a new migration to create the table again in your new engine. But if your migrations for that table ONLY touch the table your trying to move, then it’s as easy as…
1) Move ALL migration files for the db table from engine X to engine Y (this includes the migrations that created the table, added columns to it, renamed it, etc)
rake app:db:drop app:db:create && rake app:db:migrate app:db:test:prepare from within engine X and engine Y
…and you’re done. You’ve moved your database table from engine X to engine Y!
The crazy thing is, when you run
rake db:migrate from your wrapping Rails app (the one that requires all your engines), it won’t run any new migrations. To the wrapping Rails app (ie your production server), there are no new migrations. It’s pulling the same migrations from a different place, so it doesn’t notice a difference.
This makes refactoring and moving tables around 100x easier, and I loooove me some easy refactorings!
About the AuthorMore Content by Ben Smith