最近在项目里尝试使用seeds做staging的数据。而不是靠手动添加。
原因有三个,一是为了数据的可控性。二是,目前后台开发滞后于前台开发。三是,通过创建数据了解项目。
认为开发最开始的阶段,由于需求不明确,用最“友善”的数据就可以了,随着大体框架的确认,再做进一步的改进。
随着开发的进行,遇到了以下问题(没使用seeds的经验,囧)。
- 随着数据增多,变得不好管理。
- 当数据更新的时候,seeds 应该是可以被反复执行的。
- staging部署后,是否应该被自动执行
为了解决这些问题,做了一个简单的调查,笔记如下。
如何理解seeds data?
Minimum amount data to get your app fully functional -- railscasts 179
Initial data to the database is called seeding, and is distinct from migrations, which are for managing changes to the schema.
Use the seed for staging. -- Engineering Long-Lasting Software
Tips
使用
find_or_create_by
和delete_all
,保证seeds文件可以被反复执行。-
使用单独的文件存放
比如一个movie有两个字段,name,director想要导入的数据有
Good Will Hunting | Ben Affleck
Star Trek | J.J. Abrams
......把这些数据放到一个单独的文件内,是个比较不错的选择。
可以在seed内使用fixtures和factory_girl
# for fixtures
require "active_record/fixtures"
Fixtures.create_fixtures("#{Rails.root/test/fixtures}", "operating_systems")
# for factory_girl
# read more: http://stackoverflow.com/a/17118006/2477886
require 'factory_girl_rails'
10.times do
FactoryGirl.create :user
end
两个相关的gem
- populator
提供了一些DSL,在就是把文件放到了rake task内。觉得挺好的,但不是必须的。 - seed-fu
对原有的seeds做了极大的改进。
特性有:-
更好的语法
User.seed(:id, { :id => 1, :login => "jon", :email => "jon@example.com", :name => "Jon" }, { :id => 2, :login => "emily", :email => "emily@example.com", :name => "Emily" } )
-
更好的组织种子数据的方式
seed_fu可以根据model将种子数据放在不同的文件内。
比如:db/fixtures/users.rb db/fixtures/movies.rb
并且有相应的generator。
默认有输出
如果是seeds的话需要puts。可以和Capistrano集成。
容易使用,学习成本较低。
-
建议
使用seeds时,应注意到seeds是会被持续改进和反复执行的,所以应该使用find_or_create_by, delete_all之类的一些技巧。
建议使用seed_fu,使用容易,并且会带来很大的便利。