This page explains how we create seed data.
We use the Rails convention of putting our seed data files here:
/db/seeds/
We create a YAML file for our seed users:
/db/seeds/users.yml
The users YAML file defines each user's fields like this:
alice:
name: "Alice Adams"
mail: "alice@example.com"
bob:
name: "Bob Brown"
mail: "bob@example.com"
carol:
name: "Carol Cox"
mail: "carol@example.com"
/lib/tasks/We use a rake file for our seeds:
/lib/tasks/db_seed_users.rakeThe task provides the rake namespace, runs any setup tasks, then calls a normal ruby method:
# rake db:seed:users
namespace :db do
namespace :seed do
namespace :users do
task :default => %w(environment) do
db_seed_users
end
end
end
end
The normal ruby method loads the YAML file and iterates on each user:
# Seed multiple users by loading the YAML file
def db_seed_users
path=Rails.root.join('db','seeds','users.yml')
puts "Seeding file #{path}"
File.open(path) do |file|
YAML.load_documents(file) do |doc|
doc.keys.sort.each{|key|
puts "Seeding key #{key}"
attributes = doc[key]
db_seed_user(attributes)
}
}
end
end
# Seed one user
def db_seed_user(attributes)
# Do any user specific setup here...
User.create(attributes)
end
To run the rake task:
rake db:seed:users
We want to be able to run our seed task more than once and still get produce same set of users.
To do this, we add code that checks to see if the user already exists, and if so, skips creating that user:
# Seed one user
def db_seed_user(attributes)
mail = attributes['mail']
user = User.find_by_mail(mai)
if user
puts "This email address exists: #{mail}"
else
puts "This email address is new: #{mail}"
User.create(attributes)
end
end
/db/seeds/teams.ymlThe teams YAML file defines each team's fields like this:
red:
name: "Red Team"
green:
name: "Green Team"
blue:
name: "Blue Team"
We create a similar rake file:
/lib/tasks/db_seed_teams.rakeWe create a similar inner method:
# Seed one team
def db_seed_team(attributes)
Team.create(attributes)
end
To run the rake task:
rake db:seed:teams
class Team < ActiveRecord::Base
has_one :lead, :class => user
...
end
We add a lookup field to the team YAML file:
red:
name: "Red Team"
lead: "alice@example.com"
green:
name: "Green Team"
lead: "bob@example.com"
blue:
name: "Blue Team"
lead: "carol@example.com"
We add code to the inner method to look up the lead user:
# Seed one team
def db_seed_team(attributes)
attributes['lead'] = User.find_by_mail(attributes['lead'])
Team.create(attributes)
end