Data Migrations:
之前写到过,所有的migrations文件都是有ruby代码组成,而且migration中的ruby代码可以和Rails中的其他部分代码进行交互,特别是model类。因此使用migration可以很方便的完成各种数据迁移和操作开发环境数据库内的数据。一下展示了两种截然不同的data migration的应用场景:载入开发环境数据和在不用的数据版本间切换。
Loading Data with Migrations:
在实际开发中,我们常常需要向数据库中插入大量的基础数据,例如各种lookup table的记录(即编码表),产品目录等。在以往的开发过程中,开发人员往往手动书写sql语句来完成基础数据的填充。但是sql脚本总是难以维护和重 用。而Rails Migration则使这些工作变的简单,只需在migration中建立一些单纯的数据迁移的migration,(单单填充数据,而不会影响到表结构 改变的migration)就可以轻松的完成需要的工作。
请注意,这里提到的基础数据是有实际应用意义的数据,和Rails Test中提到的测试用数据是不同的事情。
假设系统中的discounts需要添加一些基础数据,可以使用以下的代码进行操作:
请注意,这里提到的基础数据是有实际应用意义的数据,和Rails Test中提到的测试用数据是不同的事情。
假设系统中的discounts需要添加一些基础数据,可以使用以下的代码进行操作:
class TestDiscounts < ActiveRecord::Migration
def self.up
down
rails_book_sku = Sku.find_by_sku("RAILS-B-00")
ruby_book_sku = Sku.find_by_sku("RUBY-B-00")
auto_book_sku = Sku.find_by_sku("AUTO-B-00")
discount = Discount.create(:name => "Rails + Ruby paper",
:action => "DEDUCT_AMOUNT",
:amount => "15.00")
discount.skus = [rails_book_sku, ruby_book_sku]
discount.save
discount = Discount.create(:name => "Automation Sale",
:action => "DEDUCT_PERCENT",
:amount => "5.00")
discount.skus = [auto_book_sku]
discount.save
end
def self.down
Discount.delete_all
end
end
在上述代码中,migration充分运用了与现有Active Record交互的能力,利用已有的model类Sku从数据库中读取已有的记录,然后与需要新建的discount类进行关联,最后将填充完成的discount进行持久化,写入数据库中。
请注意,在self.up方法的开头,调用了down方法,而down方法中会将discounts中的所有记录进行删除,这样在执行migration就不会插入重复数据了,这是在一种在data-only的数据迁移中惯用的一种模式。
请注意,在self.up方法的开头,调用了down方法,而down方法中会将discounts中的所有记录进行删除,这样在执行migration就不会插入重复数据了,这是在一种在data-only的数据迁移中惯用的一种模式。
Loading Data from Fixtures
fixtures中往往存放了测试用的填充数据,但是可以在migration使用fixtures完成基础数据迁移的功能。假设以下的一个应用场景:
在系统中有一张users表,需要事先导入一些用户数据。首先在应用的db/migrate/下建一个dev_data目录,在这个目录中新建一个users.yml文件,该文件内容如下:
在系统中有一张users表,需要事先导入一些用户数据。首先在应用的db/migrate/下建一个dev_data目录,在这个目录中新建一个users.yml文件,该文件内容如下:
dave: name: Dave Thomas status: admin mike: name: Mike Clark status: admin fred: name: Fred Smith status: audit然后使用命令:ruby script/generate migration load_users_data 生成一个migration文件,打开该文件,添加以下代码:
require 'active_record/fixtures'
class LoadUserData < ActiveRecord::Migration
def self.up
down
directory = File.dirname(__FILE__) + "/dev_data/"
Fixtures.create_fixtures(directory, "users")
end
def self.down
User.delete_all
end
end
这段代码直接从事先建好的yml文件中加载数据,并写入数据库,完成了基础数据的填充。