Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. 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. For example, one model I have is themes. I have a theme.rb file in /db/fixtures that looks like this:

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. 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. If I do that, because themes belong to other objects and their id's change upon this re-initialization, all links are broken.

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?

If not, what is the best way to seed the database?

I will truly appreciate long and thought out answers that incorporate best practices.

like image 987
Tony Avatar asked Apr 17 '09 16:04

Tony


People also ask

What is DB seed in rails?

Rails seed files are a useful way of populating a database with the initial data needed for a Rails project. The Rails db/seeds. rb file contains plain Ruby code and can be run with the Rails-default rails db:seed task.

What is Seeds RB?

The seeds.rb file is where the seed data is stored, but you need to run the appropriate rake task to actually use the seed data. Using rake -T in your project directory shows information about following tasks: rake db:seed.


2 Answers

Updating since these answers are slightly outdated (although some still apply).

Simple feature added in rails 2.3.4, db/seeds.rb

Provides a new rake task

rake db:seed 

Good for populating common static records like states, countries, etc...

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):

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

For Rails 3.x use 'ActiveRecord::Fixtures' instead of 'Fixtures' constant

require 'active_record/fixtures' ActiveRecord::Fixtures.create_fixtures("#{Rails.root}/test/fixtures", "fixtures_file_name") 
like image 114
3 revs, 3 users 82% Avatar answered Oct 13 '22 06:10

3 revs, 3 users 82%


Usually there are 2 types of seed data required.

  • 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).

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.

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.

like image 39
james2m Avatar answered Oct 13 '22 04:10

james2m