你如何改变你的Rails应用程序数据?

我已经看到很多关于ActiveRecord迁移的讨论,以及它们是否应该用于更改应用程序中的数据,有些人说是,有些人说不。 我的问题是,如果您没有使用迁移来执行此操作,那么您使用的是什么? 你写的另一个脚本?

我之后提出了关于替代方法的建议以及为什么它们可能比仅仅使用迁移更好。

如果您使用提供的,会出现一个问题

rake db:reset 

 rake db:schema:load 

任务,使用schema.rb作为设置数据库的基础。 因此,没有数据加载,你就被卡住了。

在你应该得到的Rails,第三版的敏捷Web开发中 (如果Ruby书是“Pickaxe”一书,这本书应该是“Hammock”,顺便说一句?)如果你还没有这样做,DHH说:

……迁移并不意味着携带种子数据。 它们在性质上太过时间,无法可靠地做到这一点。 迁移是为了让您从一个版本的架构到下一个版本,而不是从头开始创建一个新的架构 – 我们有db / schema.rb文件。

因此,只要您真正开始使用真正的应用程序,人们就不会在设置应用程序时运行早期迁移。 它们将从db / schema.rb中存储的任何版本开始,并忽略所有先前的迁移。 这意味着迁移创建的任何数据都不会进入数据库,因此您无法依赖它。

有许多替代方法可以获得更永久的种子数据。 最简单的可能只是在db / seed.rb中创建一个新文件,其中包含那些将进行设置的Product.create调用。 然后可以在rake db:schema之后调用此文件:load创建初始模式。

很多时候,迁移是最合适的,不能用单独的脚本替换。 想象一下以下场景:应用程序已经在使用实时数据; 代码列包含“name-zip_code”forms的代码(是的,我知道它很丑,但它发生了),你想把它分成两列,’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 

在这种情况下,在将数据传输到名称和邮政编码列之前,无法删除代码列。

当我需要修改数据库中的一些数据时,我将创建一个Rake任务来运行一些库函数来完成工作。 这样,数据操作将是可重复的,并且如果需要,也可以从迁移中运行。