Quantcast
Viewing all articles
Browse latest Browse all 5

How To Use Fixtures to Populate Your Database in Rails

UPDATE: I’ve been using this method for awhile now: http://railspikes.com/2008/2/1/loading-seed-data

Seed data is data that the app is dependent on. It is data that has to exist if you were to wipe the database clean and reload your schema. Some examples would be a list of cities/states, a list of categories, or the initial ‘admin’ user account.

Most people looking at this thread want seed data rather than to populate their database with test/generated content. For the latter, you can go the route below or try Forgery

This is a response to the email I’ve been getting asking me how to use fixtures to load data into a database.

You want to create dummy entries in your Rails app, either for testing, for development, or for production, to make your site appear popular. Whatever the reason, populating your database can be done easily using fixtures.

While rake/fixtures/migrations can get a lot more complex, this will be a brief introductory example.

Initial App setup

$ rails characters
$ cd characters/

Edit config/database.yml – We only need a development database. So open up PHPMyAdmin or the MySQL command shell and:

mysql> CREATE database characters_development;
Query OK, 1 row affected (0.00 sec)

(I’m assuming you’re using MySQL. You can use anything; SQLite, Postgres, etc..)

Create a model and a table in the database (using a migration)

$ script/generate model Character
      exists  app/models/
      exists  test/unit/
      exists  test/fixtures/
      create  app/models/character.rb
      ....

$ vim db/migrate/001_create_characters.rb

Sexy migration:

class CreateCharacters < ActiveRecord::Migration
  def self.up
    create_table :characters do |t|
      t.string  :name, :alias, :motto
      t.timestamps
    end
  end

  def self.down
    drop_table :characters
  end
end

Now migrate development (default environment):

$ rake db:migrate

Create the characters fixture

$ vim test/fixtures/characters.yml


This is a YAML file. It is easy to read and easy to edit. (One may also use the CSV format, extension .csv).

Some notes:

  • Each model has a corresponding fixture file with the same name in the test/fixtures/ path in your app’s root directory.
  • Each ‘fixture’ is a record in the database table, and consists of a label, and then values for each field (i.e., name, age, etc..).
  • Optional fields can be skipped. They will default to either NULL, or their default value set in the database.
  • The id doesn’t need to be specified. It will be auto-incremented automatically, but be careful of conflicts if you’re specifying the ID for some fixtures and not others.
  • Whitespace matters. Make it purty.
  • You may embed Ruby code in the fixture file, in both the YAML and CSV fixture formats. (i.e., <% f() -%> or created_at: <%= Time.now %>)
  • To load fixtures, you use rake db:fixtures:load. This loads the fixtures into your current environment (can be set via RAILS_ENV shell var or in config/environment.rb).One thing that might be confusing is the fact that fixtures reside in test/. Many people believe that fixtures can only be used in the test environment, but this is not the case.
  • When a fixture are loaded, any data previously in the table will be wiped out. You don’t need to fear altering or losing your test data when testing (i.e., destroy methods, …), just reload the fixtures. In the test environment, fixtures may be loaded before each test case is run by using the fixtures method (fixtures :employees, :orders, …). Keep in mind that you’re using a freshly loaded fixtures between every case method (if you’re loading).

This is what our fixture file should look like. I will dissect it below:

riddler:
  name: Edward Nashton
  alias: Riddler
  motto: Riddle me this, riddle me that

pp:
  name: Peter Parker
  alias: Spiderman
  motto: One for JJ
  created_at: <%= Time.now %>
  updated_at: <%= Time.now %>

JILL:
  id: 101
  name: Jill Valentine
  motto: Im a member of S*T*A*R*S

dan_forden:
  name: Dan Forden
  motto: Toasty!

hotness:
  name: Sorceress
  motto: Time is mana

Airplane:
  name: Steve McCroskey
  motto: Looks like I picked the wrong week to quit sniffing glue.

Let’s examine the first fixture:

riddler:
  name: Edward Nashton
  alias: Riddler
  motto: Riddle me this, riddle me that
riddler:

This is a name for the fixture. It begins at the beginning of the line, and it doesn’t matter what you call it. That information is not saved in the database and you might never use it. Ideally, names should be descriptive. You may also just go generic, “person1, person2, person3″ etc.

When using the CSV format, fixture names are generated automatically and are in this format:

model_name-counter

In our example above, our fixtures would be named character-1, character-2, etc.

  name: Edward Nashton
  alias: Riddler
  motto: Riddle me this, riddle me that

These three are the values this fixture (record) will have in the database. They go under the fixture name, tabbed or spaced evenly. When going on to the next fixture, just leave a blank line.

The above is like doing this:

>> r = Character.new
>> r.name = 'Edward Nashton'
>> r.alias = 'Riddler'
>> r.motto = 'Riddle me this, riddle me that'
>> r.save

id, created_at and updated_at are optional, but may be specified. Keep in mind that this file is going to be preprocessed with Ruby, so you may embed Ruby code (ERb) anywhere in the file.

Load Fixture into Development Database

This loads fixtures into the current RAILS_ENV, which, by default, is development.

$ rake db:fixtures:load

If you check your database now, you will find the fixtures you just loaded residing in the specific table. Let’s poke at this table in the Rails console.

$ script/console
>> them = Character.find(:all)
=> [#> them[0].name
=> Edward Nashton

>> them[0].alias
=> Riddler

>> them[0].motto
=> Riddle me this, riddle me that

See these links for more info:

External links


Viewing all articles
Browse latest Browse all 5

Trending Articles