在Rails中建立数据库的最佳方式是什么?

问题描述:

我有一个rake任务,填充我的rails应用程序中的一些初始数据。例如,国家,州,移动运营商等在Rails中建立数据库的最佳方式是什么?

我现在设置的方式是,我有一堆创建语句在/ db /夹具文件和一个耙子任务处理它们。例如,我拥有的一个模型是主题。我在/ DB /夹具一个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" 

这里的想法是,我想安装一些股票主题供用户下手。我有这个方法的问题。

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

我的问题是首先,这是处理播种数据库的好方法吗?在之前的文章中,这是向我推荐的。

如果是这样,我该如何硬编码ID,并有什么缺点呢?

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

我真的很感激长期以来想出的结合最佳实践的答案。

+0

你能接受更新的答案吗? – 2011-02-24 20:03:38

+0

刚刚做到了。感谢提醒 – Tony 2011-03-01 15:33:17

正在更新,因为这些答案略有过时(尽管有些仍然适用)。

在rails 2.3.4,db/seeds中添加的简单功能。RB

提供了一个新的rake任务

rake db:seed 

适合填充普通的静态记录,如州,国家等等

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

*需要注意的是,你可以,如果你使用的灯具已经创建它们以通过将以下内容放入您的seeds.rb文件(来自railscast情节)来填充db:seed任务:

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

对于滑轨3.x的使用的ActiveRecord ::比赛时间“而不是“灯具”恒定

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

不使用显式创建,而是使用YAML文件。使用简单的语法,您可以填充对象的所有值。实际上,如果您对轨道测试有所了解,那么这是测试数据库种子的标准方法。 看看这些网页:
http://railspikes.com/2008/2/1/loading-seed-data http://quotedprintable.com/2007/11/16/seed-data-in-rails

+5

我知道关于轨道测试。我没有测试我的应用程序,我正在为我的数据库进行开发和生产。此外,您发给我的文章最后支持我的数据库播种方法。 – Tony 2009-04-17 17:39:12

最好的办法是使用灯具。

注意:请记住,灯具做直接插入,不使用你的模型,所以如果你有回调填充数据,你需要找到一个解决方法。

将它添加到数据库迁移中,这样每个人都可以在更新时获取它。在ruby/rails代码中处理所有的逻辑,所以你永远不必搞乱显式的ID设置。

+0

如果我需要更改初始数据,使用迁移时可能会变得杂乱无章。你的第二个评论没有意义。通过外键链接将被销毁 – Tony 2009-04-17 20:15:04

factory_girl听起来像它会做你正在努力实现的。您可以在默认定义中定义所有常用属性,然后在创建时覆盖它们。您也可以通过一个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') 

当骗子用它可以确实很快与各协会填充数据库,而无需做手脚配件(呸)。

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

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

通常有需要2种类型的种子数据。

  • 基本数据根据您的应用程序的核心可能依赖。我把这称为共同的种子。
  • 环境数据,例如为了开发应用程序,我们可以在本地处理应用程序时使用一堆已知状态的数据(上面的Factory Girl答案涵盖了此类数据)。

根据我的经验,我总是遇到需要这两种类型的数据。所以我放在一起a small gem that extends Rails' seeds,并让你添加db/seeds /下的多个常见种子文件和db/seeds/ENV下的任何环境种子数据,例如db/seeds/development。

我发现这种方法足以让我的种子数据的一些结构,给我力量,建立我在已知状态下开发或临时环境只是通过运行:

rake db:setup 

赛程是脆弱的,古怪像常规的sql转储那样维护。

使用seeds.rb文件或FactoryGirl是伟大的,但它们分别适用于固定数据结构和测试。

seedbank宝石可能会给你更多的控制和模块化你的种子。它插入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有一个内置的方式解释here种子数据。

另一种方法是将宝石用于更高级或易于播种,例如:seedbank

这个gem的主要优点和我使用它的原因是它具有高级功能,如数据加载依赖性和每个环境种子数据。

添加一个最新的答案,因为这个答案是第一次在谷歌。