Reputation: 1273
Is it possible to run one or two blocks within my seeds.rb code like you can with tests and gemfiles?
For example, if I had the following code in my seeds.rb file, could I just seed the Employee
model?
20.times do
Employee.create!(name: "Bob",
email: Faker::Internet.email)
end
20.times do
User.create!(name: "Hank",
password: "foobar")
end
If this were my entire seeds.rb file, running rake db:seed
would create 20 additional users when I only want to add more employees.
Upvotes: 1
Views: 3831
Reputation: 19879
I've used the following setup for a couple of years now to help my sanity.
In db/seeds I have the following files:
001_providers.rb
005_api_users.rb
007_mailing_lists.rb
010_countries.rb
011_us_states.rb
012_canadian_provinces.rb
013_mexican_states.rb
100_world_cities.rb
101_us_zipcodes.rb
My db/seeds.rb file looks like this:
if ENV['VERSION'].present?
seed_files = Dir[File.join(File.dirname(__FILE__), 'seeds', "*#{ENV['VERSION']}*.rb")]
raise "No seed files found matching '#{ENV['VERSION']}'" if seed_files.empty?
else
seed_files = Dir[File.join(File.dirname(__FILE__), 'seeds', '*.rb')]
end
seed_files.sort_by{|f| File.basename(f).to_i}.each do |file|
require File.join(File.dirname(__FILE__), 'seeds', File.basename(file, File.extname(file)))
end
Just a bit of ruby code to let me run one or more seed files. I can now do things like this:
# run them all
bin/rake db:seed
# run just 001_providers.rb
bin/rake db:seed VERSION=001
# run all seeds for the USA (probably dangerous, but if you name your seeds right, could be useful).
bin/rake db:seed VERSION=us
One thing that is very important is that your seed files should be able to be run over and over and over and end up with a consistent state. If you run your seeds over and over you'll end up with many more users than just 20.
For example, my providers one has a main loop like this:
# providers is a hash of attributes...
providers.each_with_index do |(code, attrs), i|
p = Provider.find_by(code: code) || Provider.new(code: code) p.update!(attrs)
end
This way regardless of when I run it, I always get back exactly the providers I defined in my hash.
Upvotes: 3
Reputation: 17802
You can pass an option while running rake db:seed
like following:
rake db:seed users=yes
And, then in your code, you can access it through the following way:
20.times do
Employee.create!(name: "Bob",
email: Faker::Internet.email)
end
if ENV["users"]
20.times do
User.create!(name: "Hank",
password: "foobar")
end
end
Upvotes: 5