有时候,需要数据迁移。 随着时间的推移,更改代码,并使用您的域模型迁移不再有效和迁移失败。 什么是数据迁移的最佳实践?
我试图做一个例子来阐明这个问题:
考虑这一点。 你有一个迁移
class ChangeFromPartnerAppliedToAppliedAt < ActiveRecord::Migration
def up
User.all.each do |user|
user.applied_at = user.partner_application_at
user.save
end
end
这种运行完全正常的,当然。 后来,你需要一个架构更改
class AddAcceptanceConfirmedAt < ActiveRecord::Migration
def change
add_column :users, :acceptance_confirmed_at, :datetime
end
end
class User < ActiveRecord::Base
before_save :do_something_with_acceptance_confirmed_at
end
对你来说,没有什么问题。 它运行完美。 但是,如果你的同事今天这些都拉动, 没有运行第一个迁移的是 ,他会得到这个错误上运行的第一个迁移:
rake aborted!
An error has occurred, this and all later migrations canceled:
undefined method `acceptance_confirmed_at=' for #<User:0x007f85902346d8>
这还不是一个团队球员,他会解决您介绍的bug。 我应该怎么做?
最好的做法是:不迁移使用模型。 迁移改变方式AR地图,所以不要使用它们。 做这一切与SQL。 通过这种方式,它会永远工作。
这个:
User.all.each do |user|
user.applied_at = user.partner_application_at
user.save
end
我会做这样的
update "UPDATE users SET applied_at=partner_application_at"
这是一个完美的例子Using Models in Your Migrations
class ChangeFromPartnerAppliedToAppliedAt < ActiveRecord::Migration
class User < ActiveRecord::Base
end
def up
User.all.each do |user|
user.applied_at = user.partner_application_at
user.save
end
end
米莎的评论后编辑
class ChangeFromPartnerAppliedToAppliedAt < ActiveRecord::Migration
class User < ActiveRecord::Base
end
def up
User.update_all('applied_at = partner_application_at')
end
end
有些时候,“迁移数据”可以像上面所讨论的不被作为模式迁移的一部分执行。 有时,“迁移数据”是指“弄不好历史数据inconstancies”或“更新您的Solr / Elasticsearch人指数,所以它是一个复杂的任务。 对于这些类型的任务,看看这个宝石https://github.com/OffgridElectric/rails-data-migrations
这种宝石的设计去耦数据迁移的Rails架构迁移,所以它不会在部署时引起的停机时间,并可以很容易在整体管理