I just learned that our current practice for removing a column in an ActiveRecord migration is to hide the column from Rails before actually removing it (via an ugly hack, see below for details).
This is due to the fact that Rails caches the SHOW FULL FIELDS
query. If we don't work around that, the (long-running) migration will remove the column and by that time, Rails will have already cached the fields. Once the migration is done and the column is gone, the app will subsequently crash because INSERT
s will provide values for a non-existing column because of the cache.
Using things like clear_table_cache!
within the migration are of no use because we deploy to N servers and run the migration on just one of them. This would clear the cache on one of the servers but not all.
What we're currently doing is overriding ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter#columns
in an initializer and deploy that before running the migration.
After the migration is done, we remove the overriding initializer and deploy again.
At this point, I cannot believe we're the only ones who encounter this problem and have to work around it. Are there any other solution to this problem?
Rails 5 has added ignored_columns
to the ActiveRecord::Base
class:
Since some columns will appear or disappear at any moment, you want to make those columns invisible to AR for a while. Otherwise you could have some processes knowing about the columns and others who don't.
Here's some sample code:
class User < ApplicationRecord
self.ignored_columns = %w(employee_email)
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With