我已经看过很多关于ActiveRecord迁移的讨论,以及它们是否应该用于更改应用程序中的数据,有些人说是,有些人说不。我的问题是,如果您没有使用迁移来执行此操作,那么您使用的是什么?你写的另一个脚本吗?
我之后就其他方式提出建议,以及为什么它们可能比仅仅使用迁移更好。
答案 0 :(得分:14)
如果您使用提供的
,则会出现一个问题rake db:reset
和
rake db:schema:load
任务,使用schema.rb
作为设置数据库的基础。所以没有数据被加载而且你被卡住了。
在Agile Web Development with Rails, Third Edition,你应该得到的(如果Ruby书是“镐”书,如果这是“吊床”书,顺便说一句?)如果你还没有这样做,DHH说:
......迁移并非真正意义上的 携带种子数据。他们太暂时了 在性质上可靠地做到这一点。 迁移来自于此 一个版本的架构到下一个, 不要从中创建新的架构 scratch-我们有db / schema.rb文件 为了那个原因。
所以,只要你真的 开始使用真正的应用程序, 人们不会早点跑 他们建立时的迁移 应用。他们会从 无论存储什么版本 db / schema.rb并忽略所有这些 以前的迁移。这意味着 迁移创建的任何数据 从来没有进入数据库,所以 你不能依赖它。
有很多 有更多的替代方法 永久种子数据。最简单的是 可能只是为了创建一个新文件 db / seed.rb,包含那些 Product.create会调用它们 建立。然后可以调用此文件 rake db:schema:load之后创建 初始架构。
答案 1 :(得分:4)
很多时候,迁移是最合适的,不能用单独的脚本替换。想象一下以下场景:应用程序已经在使用实时数据;代码列包含“name-zip_code”形式的代码(是的,我知道它很难看,但它发生了),你想把它分成两列,'name'和'zip_code',同时摆脱'代码栏。
def self.up
add_column :companies, :zip_code, :integer
add_column :companies, :name, :string
Company.reset_column_information
Company.find(:all).each do |company|
name, zip_code = company.code.split('-')
company.update_attributes(:name => name, :zip_code => zip_code)
end
remove_column :companies, :code
end
在这种情况下,在将数据传输到名称和邮政编码列之前,无法删除代码列。
答案 2 :(得分:1)
当我需要修改数据库中的一些数据时,我将创建一个Rake任务来运行一些库函数来完成工作。这样,数据操作将是可重复的,如果需要,也可以从迁移中运行。