简体   繁体   English

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

[英]What is the best way to seed a database in Rails?

I have a rake task that populates some initial data in my rails app. 我有一个rake任务,在我的rails应用程序中填充一些初始数据。 For example, countries, states, mobile carriers, etc. 例如,国家,州,移动运营商等

The way I have it set up now, is I have a bunch of create statements in files in /db/fixtures and a rake task that processes them. 我现在设置它的方式是,我在/ db / fixtures中的文件中有一堆create语句,还有一个处理它们的rake任务。 For example, one model I have is themes. 例如,我有一个模型是主题。 I have a theme.rb file in /db/fixtures that looks like this: 我在/ 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"

The idea here is that I want to install some stock themes for users to start with. 这里的想法是我想为用户安装一些股票主题。 I have a problem with this method. 我有这个方法的问题。

Setting the ID does not work. 设置ID不起作用。 This means that if I decide to add a theme, let's call it 'Red', then I would simply like to add the theme statement to this fixture file and call the rake task to reseed the database. 这意味着如果我决定添加一个主题,让我们称之为“红色”,那么我只想将主题语句添加到此fixture文件并调用rake任务来重新设置数据库。 If I do that, because themes belong to other objects and their id's change upon this re-initialization, all links are broken. 如果我这样做,因为主题属于其他对象,并且在重新初始化时它们的id发生了变化,所有链接都会被破坏。

My question is first of all, is this a good way to handle seeding a database? 我的问题首先是,这是处理数据库播种的好方法吗? In a previous post, this was recommended to me. 在之前的帖子中,我向你推荐了这个。

If so, how can I hard code the IDs, and are there any downsides to that? 如果是这样,我怎么能对ID进行硬编码,这有什么缺点吗?

If not, what is the best way to seed the database? 如果没有,那么种子数据库的最佳方法是什么?

I will truly appreciate long and thought out answers that incorporate best practices. 我将真正感谢包含最佳实践的长期和深思熟虑的答案。

Updating since these answers are slightly outdated (although some still apply). 更新,因为这些答案有点过时(虽然有些仍然适用)。

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

Provides a new rake task 提供新的rake任务

rake db:seed

Good for populating common static records like states, countries, etc... 适合填充州,国家等常见静态记录...

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

*Note that you can use fixtures if you had already created them to also populate with the db:seed task by putting the following in your seeds.rb file (from the railscast episode): *请注意,如果您已经创建了fixtures,则可以使用fixture来填充db:seed任务,方法是将以下内容放入seeds.rb文件中(来自railscast剧集):

require 'active_record/fixtures'
Fixtures.create_fixtures("#{Rails.root}/test/fixtures", "operating_systems")

For Rails 3.x use 'ActiveRecord::Fixtures' instead of 'Fixtures' constant 对于Rails 3.x,使用'ActiveRecord :: Fixtures'而不是'Fixtures'常量

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

Usually there are 2 types of seed data required. 通常需要2种种子数据。

  • Basic data upon which the core of your application may rely. 应用程序核心可能依赖的基本数据 I call this the common seeds. 我称之为普通种子。
  • Environmental data , for example to develop the app it is useful to have a bunch of data in a known state that us can use for working on the app locally (the Factory Girl answer above covers this kind of data). 环境数据 ,例如开发应用程序,有一堆数据处于已知状态,我们可以用来在本地处理应用程序(上面的Factory Girl答案涵盖了这种数据)。

In my experience I was always coming across the need for these two types of data. 根据我的经验,我总是需要这两种类型的数据。 So I put together a small gem that extends Rails' seeds and lets you add multiple common seed files under db/seeds/ and any environmental seed data under db/seeds/ENV for example db/seeds/development. 所以我整理了一个小的宝石,它扩展了Rails的种子,并允许你在db / seeds /下添加多个常见的种子文件,并在db / seeds / ENV下添加任何环境种子数据,例如db / seeds / development。

I have found this approach is enough to give my seed data some structure and gives me the power to setup my development or staging environment in a known state just by running: 我发现这种方法足以为我的种子数据提供一些结构,并且让我能够通过运行以下方式在已知状态下设置我的开发或登台环境:

rake db:setup

Fixtures are fragile and flakey to maintain, as are regular sql dumps. 与常规的sql转储一样,Fixtures易于维护和维护。

factory_bot sounds like it will do what you are trying to achieve. factory_bot听起来像它会做你想要实现的。 You can define all the common attributes in the default definition and then override them at creation time. 您可以在默认定义中定义所有公共属性,然后在创建时覆盖它们。 You can also pass an id to the factory: 您也可以将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')

When used with faker it can populate a database really quickly with associations without having to mess about with Fixtures (yuck). 当与faker一起使用时,它可以非常快速地使用关联填充数据库,而不必使用Fixtures(yuck)。

I have code like this in a rake task. 我在rake任务中有这样的代码。

100.times do
    Factory(:company, :address => Factory(:address), :employees => [Factory(:employee)])
end

Using seeds.rb file or FactoryBot is great, but these are respectively great for fixed data structures and testing. 使用seeds.rb文件或FactoryBot非常棒,但它们分别适用于固定数据结构和测试。

The seedbank gem might give you more control and modularity to your seeds. seedbank宝石可能会为您的seedbank提供更多控制和模块化。 It inserts rake tasks and you can also define dependencies between your seeds. 它插入rake任务,您还可以定义种子之间的依赖关系。 Your rake task list will have these additions (eg): 您的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

Rails has a built in way to seed data as explained here . 轨道有一个内置的方式解释种子数据在这里

Another way would be to use a gem for more advanced or easy seeding such as: seedbank . 另一种方法是使用宝石进行更高级或更容易的播种,例如: 种子库

The main advantage of this gem and the reason I use it is that it has advanced capabilities such as data loading dependencies and per environment seed data. 这个gem的主要优点和我使用它的原因是它具有高级功能,如数据加载依赖项和每个环境种子数据。

Adding an up to date answer as this answer was first on google. 添加最新答案,因为此答案首先在谷歌上。

The best way is to use fixtures. 最好的方法是使用灯具。

Note: Keep in mind that fixtures do direct inserts and don't use your model so if you have callbacks that populate data you will need to find a workaround. 注意:请记住,灯具会直接插入并且不使用您的模型,因此如果您有填充数据的回调,则需要找到解决方法。

Add it in database migrations, that way everyone gets it as they update. 将其添加到数据库迁移中,这样每个人都可以在更新时获取它。 Handle all of your logic in the ruby/rails code, so you never have to mess with explicit ID settings. 处理ruby / rails代码中的所有逻辑,因此您永远不必弄乱显式ID设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM