Running "rails db:truncate_all" truncates the data_migrations table
I just found this out the hard way. 😜 If you run the newly-introduced rails db:truncate_all task (e.g., because you want to re-seed your DB), it will also truncate your data_migrations table. As a result, the next time you run rails db:migrate:with_data (or an equivalent command), it will attempt to run all of your data migrations.
The code for truncation is in ActiveRecord::ConnectionAdapters::DatabaseStatements which, as you can see, has logic for ignoring schema_migrations and ar_internal_metadata but not (obviously) data_migrations.
While the problem is clear, I'm unsure of a maintainable solution. From the looks of it there's no way we can easily hook into the method from the outside to ignore an additional table. I have three ideas in mind:
- Monkey-patching the method. This doesn't feel right, and it's also not maintainable in the long run (especially when you start considering that different Rails versions have different implementations).
- Implement a custom
rails db:truncate_all:with_datatask that ignoresdata_migrations, but (1) it's still not very maintainable, because we'd have to copy-paste the AR code, and (2) I don't think it would play well with other tasks that truncate the DB, such asdb:seed:replant. - Replace the
db:truncatetask to: (1) get the contents of thedata_migrationstable, (2) run the original task (thereby truncating the table), (3) import the data back intodata_migrations. This is pretty hacky, but it might be the most maintainable solution because we don't have to deal with Rails internals.
Let me know if you have any thoughts/feedback on the above. I'd be happy to give this a try!
It would be great to have db:seed:replant:with_data and db:truncate_all:with_data tasks to keep data_migrations table intact 👍