It is believed that rails migrations are atomic transactions, that is, if there is an error, the whole thing is rolled back. Well I came to an interesting exception.
I created a migration to add an association to a model:
rails g migration AddModelOneToModelTwo model_one:references
which creates the migration to add model_one_id
to model_two
.
In this particular project, I am using mysql
, and a previous version default of the id
was int(11)
and most the tables were created like so. The current version’s default for id
is int(20)
. Running the previous migrations creates model_one_id
to be int(20)
but fails to create the reference to the id
in the model_one
table as they are not the same type. The migration therefore fails. However, the created column somehow persist, and cannot go forward or backward without manually manipulating the database. The rails console does not load because there are migrations to be run. Trying to run the migration again throws an error with field model_one_id
already exists, but this partial change cannot be rollbacked. Stuck!
What to do?
- This migration needs to be adjusted so that the
model_one_id
column is of typeint(11)
by adding this to the code:type: :integer
. - In the
mysql
CLI, select the database of interest by:use database_name;
- Manually delete the already created
model_one_id
from themodel_two
table:ALTER TABLE table_name DROP COLUMN column_name;
- Check the state of the table with
show full columns from TABLE;
- Get out of the
mysql
CLI. - Run the migration.
- That’s it.