在Rails中为数据库设定种子的最佳方法是什么?

Ton*_*ony 78 ruby database ruby-on-rails seed task

我有一个rake任务,在我的rails应用程序中填充一些初始数据.例如,国家,州,移动运营商等

我现在设置它的方式是,我在/ db/fixtures中的文件中有一堆create语句,还有一个处理它们的rake任务.例如,我有一个模型是主题.我在/ db/fixtures中有一个theme.rb文件,如下所示:

Theme.delete_all
Theme.create(:id => 1, :name=>'Lite', :background_color=>'0xC7FFD5', :title_text_color=>'0x222222',
                      :component_theme_color=>'0x001277', :carrier_select_color=>'0x7683FF', :label_text_color=>'0x000000',
                      :join_upper_gradient=>'0x6FAEFF', :join_lower_gradient=>'0x000000', :join_text_color=>'0xFFFFFF',
                      :cancel_link_color=>'0x001277', :border_color=>'0x888888', :carrier_text_color=>'0x000000', :public => true)

Theme.create(:id => 2, :name=>'Metallic', :background_color=>'0x000000', :title_text_color=>'0x7299FF',
                      :component_theme_color=>'0xDBF2FF', :carrier_select_color=>'0x000000', :label_text_color=>'0xDBF2FF',
                      :join_upper_gradient=>'0x2B25FF', :join_lower_gradient=>'0xBEFFAC', :join_text_color=>'0x000000',
                      :cancel_link_color=>'0xFF7C12', :border_color=>'0x000000', :carrier_text_color=>'0x000000', :public => true)

Theme.create(:id => 3, :name=>'Blues', :background_color=>'0x0060EC', :title_text_color=>'0x000374',
                      :component_theme_color=>'0x000374', :carrier_select_color=>'0x4357FF', :label_text_color=>'0x000000',
                      :join_upper_gradient=>'0x4357FF', :join_lower_gradient=>'0xffffff', :join_text_color=>'0x000000',
                      :cancel_link_color=>'0xffffff', :border_color=>'0x666666', :carrier_text_color=>'0x000000', :public => true)
puts "Success: Theme data loaded"
Run Code Online (Sandbox Code Playgroud)

这里的想法是我想为用户安装一些股票主题.我有这个方法的问题.

设置ID不起作用.这意味着如果我决定添加一个主题,让我们称之为"红色",那么我只想将主题语句添加到此fixture文件并调用rake任务来重新设置数据库.如果我这样做,因为主题属于其他对象,并且在重新初始化时它们的id发生了变化,所有链接都会被破坏.

我的问题首先是,这是处理数据库播种的好方法吗?在上一篇文章中,我向你推荐了这个.

如果是这样,我怎么能对ID进行硬编码,这有什么缺点吗?

如果没有,那么种子数据库的最佳方法是什么?

我将真正感谢包含最佳实践的长期和深思熟虑的答案.

ajh*_*406 110

更新,因为这些答案有点过时(虽然有些仍然适用).

在rails 2.3.4,db/seeds.rb中添加了简单的功能

提供新的rake任务

rake db:seed
Run Code Online (Sandbox Code Playgroud)

适合填充州,国家等常见静态记录...

http://railscasts.com/episodes/179-seed-data

*请注意,如果您已经创建了fixtures,则可以使用fixture来填充db:seed任务,方法是将以下内容放入seeds.rb文件中(来自railscast剧集):

require 'active_record/fixtures'
Fixtures.create_fixtures("#{Rails.root}/test/fixtures", "operating_systems")
Run Code Online (Sandbox Code Playgroud)

对于Rails 3.x,使用'ActiveRecord :: Fixtures'而不是'Fixtures'常量

require 'active_record/fixtures'
ActiveRecord::Fixtures.create_fixtures("#{Rails.root}/test/fixtures", "fixtures_file_name")
Run Code Online (Sandbox Code Playgroud)


jam*_*s2m 27

通常需要2种种子数据.

  • 应用程序核心可能依赖的基本数据.我称之为普通种子.
  • 环境数据,例如开发应用程序,有一堆数据处于已知状态,我们可以用来在本地处理应用程序(上面的Factory Girl答案涵盖了这种数据).

根据我的经验,我总是需要这两种类型的数据.所以我整理了一个小的宝石,它扩展了Rails的种子,并允许你在db/seeds /下添加多个常见的种子文件,并在db/seeds/ENV下添加任何环境种子数据,例如db/seeds/development.

我发现这种方法足以为我的种子数据提供一些结构,并且让我能够通过运行以下方式在已知状态下设置我的开发或登台环境:

rake db:setup
Run Code Online (Sandbox Code Playgroud)

与常规的sql转储一样,Fixtures易于维护和维护.


Hat*_*es_ 25

factory_bot听起来像它会做你想要实现的.您可以在默认定义中定义所有公共属性,然后在创建时覆盖它们.您也可以将ID传递给工厂:

Factory.define :theme do |t|
  t.background_color '0x000000'
  t.title_text_color '0x000000',
  t.component_theme_color '0x000000'
  t.carrier_select_color '0x000000'
  t.label_text_color '0x000000',
  t.join_upper_gradient '0x000000'
  t.join_lower_gradient '0x000000'
  t.join_text_color '0x000000',
  t.cancel_link_color '0x000000'
  t.border_color '0x000000'
  t.carrier_text_color '0x000000'
  t.public true
end

Factory(:theme, :id => 1, :name => "Lite", :background_color => '0xC7FFD5')
Factory(:theme, :id => 2, :name => "Metallic", :background_color => '0xC7FFD5')
Factory(:theme, :id => 3, :name => "Blues", :background_color => '0x0060EC')
Run Code Online (Sandbox Code Playgroud)

当与faker一起使用时,它可以非常快速地使用关联填充数据库,而不必使用Fixtures(yuck).

我在rake任务中有这样的代码.

100.times do
    Factory(:company, :address => Factory(:address), :employees => [Factory(:employee)])
end
Run Code Online (Sandbox Code Playgroud)

  • FactoryGirl实际上是用于代替灯具进行测试,但它也可用于将物料装入生产中.使用具有db:migrate的rake任务作为加载所有默认数据的先决条件.您可能需要使rake任务足够智能,以至于它不会创建现有数据的副本. (10认同)
  • 不建议使用FactoryGirl作为种子,[请检查此帖子](https://robots.thoughtbot.com/factory_girl-for-seed-data)。 (2认同)

Yur*_*uri 22

使用seeds.rb文件或FactoryBot很好,但这些分别适用于固定数据结构和测试.

seedbank宝石可能会给你更多的控制和模块化你的种子.它插入rake任务,您还可以定义种子之间的依赖关系.您的rake任务列表将包含以下内容(例如):

rake db:seed                    # Load the seed data from db/seeds.rb, db/seeds/*.seeds.rb and db/seeds/ENVIRONMENT/*.seeds.rb. ENVIRONMENT is the current environment in Rails.env.
rake db:seed:bar                # Load the seed data from db/seeds/bar.seeds.rb
rake db:seed:common             # Load the seed data from db/seeds.rb and db/seeds/*.seeds.rb.
rake db:seed:development        # Load the seed data from db/seeds.rb, db/seeds/*.seeds.rb and db/seeds/development/*.seeds.rb.
rake db:seed:development:users  # Load the seed data from db/seeds/development/users.seeds.rb
rake db:seed:foo                # Load the seed data from db/seeds/foo.seeds.rb
rake db:seed:original           # Load the seed data from db/seeds.rb
Run Code Online (Sandbox Code Playgroud)