Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

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.

share|improve this question
hmmm... why not do this in raw sql or Arel then ? as a side note, you have to call Article.reset_column_information before using the model or your operations will fail. – m_x Apr 29 at 17:40

Know someone who can answer? Share a link to this question via email, Google+, Twitter, or Facebook.

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.