Disentangle Schema Changes and Business Logic Changesets
Rails makes writing migrations and performing them on our database so easy!
bundle exec rails g migration CreateAllTheThings
Why, with only less than 100 keystrokes your off to the races modifying your database. What isn’t to love?
Consider that as an application increases in complexity the on-going cost of maintenance increases as well. Such maintenance and servicing cost is also increased in the event that there are limited guard rails (e.g., blue/green deploys, unit tests, automated monitoring, et cetera) available for taking a deploy from PR → master.
One simple way to improve reliability of rollouts and dis-entangling schema modifications from business logic related to that logic. Let’s look at an example.
- Product Manager A decides that we need to convert the
namefield into two fields
- We generate a Rails migration to drop the
namecolumn and add two new columns
- We perform a
CMD+Fto find and replace all the instances of
first_namein the application
- Push the change up to
staging- LGTM, force push to
masterand deploy baby!
5... minutes... later
Product Manager A: SAMMY SUPER CODER WHY IS THE SITE DOWN?!
500 errors everywhere!!
Unfortunately, Sammy Super Coder is in a tough spot at the moment, which is exasperated if they don’t have console access.
In order to rollback to the prior version we have to rollback the new business logic changes released which - depending on the deployment infrastructure - could take several minutes. Moreover, we dropped the
name column in our migration which means we have to rollback our migration two. If our application is live and integrated in the while we have an increased risk of causing downstream issues and more delay because we need to rollback our changes:
STEP 1: Rollback migration (bundle exec rails db:migrate:rollback STEP=1 STEP 2: Revert the PR STEP 3: Re-deploy the prior "safe" PR.
If we dis-entangled the migration from it’s associated business logic, as a point of hygiene, we would be able to skip STEP 1 and just revert the PR and re-deploy, resulting in less down-time and complexity due to schema changes