Lets imagine we have an Article
entity, with data imported from a legacy database. It contains an appendix
column with type integer
. This column is always filled with values 0
, 1
or nil
, so we decide to call it in_appendix
with type boolean
. We want to preserve all existent data so we convert the data like this:
class ChangeTypeAppendixColumn < ActiveRecord::Migration
def up
add_column :article, :in_appendix, :boolean
f = Article.update_all({ in_appendix: false }, { appendix: nil })
f += Article.update_all({ in_appendix: false }, { appendix: 0 })
t = Article.update_all({ in_appendix: true }, { appendix: 1 })
remove_column :article, :appendix
end
def down
...
end
end
The problem is, if someday the Article
model changes radically or ceases to exist, these migrations won't run anymore. My current solution is to create an AuxArticle
class like this:
class AuxArticle < ActiveRecord::Base
self.table_name = :article
end
class ChangeTypeAppendixColumn < ActiveRecord::Migration
def up
add_column :article, :in_appendix, :boolean
f = AuxArticle.update_all({ in_appendix: false }, { appendix: nil })
f += AuxArticle.update_all({ in_appendix: false }, { appendix: 0 })
t = AuxArticle.update_all({ in_appendix: true }, { appendix: 1 })
remove_column :article, :appendix
end
def down
...
end
end
It works but I would like to know about more elegant ways to keep existing data and at the same time prevent coupling between migrations and models.
Article.reset_column_information
before using the model or your operations will fail. – m_x Apr 29 at 17:40