What is the best way to seed a database in Rails?
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")
How to seed database with has_and_belongs_to_many
If you want to associate each Phone instance with all the categories you can do it like so:
Category.create(name:'tactile-screen')
Category.create(name:'mobile')
Category.create(name:'landline')
ids = Category.all.ids
Phone.create(name:'Home', phone:'+00 0 00 00 00 00', category_ids: ids)
Phone.create(name:'Work', phone:'+00 1 00 00 00 00', category_ids: ids)
Otherwise just create arrays of the records and you can do something like the following if you for example want to apply a random category:
categories = ['tactile-screen', 'mobile', 'landline'].map do |c|
Category.create(name: c)
end
phones = [
Phone.create(name:'Home', phone:'+00 0 00 00 00 00'),
Phone.create(name:'Work', phone:'+00 1 00 00 00 00')
]
phones.each do |p|
p.categories << categories.sample
end
If you are using Faker or FFaker you can use this nifty trick to generate random records:
require 'ffaker'
# generate a 100 random numbers
phones = 100.times.map do
Phone.create(name:'Home', FFaker::PhoneNumber.phone_number)
end
# generate between 0 and 100 random numbers
phones = ((rand * 100).floor).times.map do
Phone.create(name:'Home', FFaker::PhoneNumber.phone_number)
end
How to seed Test db just once in Rails?
You can make your seeding more efficient with the new Rails 6 insert_all
. This creates multiple records with a single insert
and does not instantiate models. OTOH it doesn't do any validation, so be careful.
DictionaryWords.insert_all([
{ word: "foo" },
{ word: "bar" },
])
Alternatively, use activerecord-import.
But it's better not to make 180,000 words at all.
The problem with seeds and fixtures is they're "one size fits all". They must encompass every possible dev and testing situation. They're fragile, one change to the seed might mysteriously break many tests which made assumptions about the fixtures. Seeds will be blown away if you need to reset your databases.
Instead, use a factory and create what you need when you need it. Use a library such as Faker to generate fake but valid data.
For example...
# Assuming you have classes called Dictionary and DictionaryWord
factory :dictionary do
end
factory :dictionary_word do
dictionary
word { Faker::Lorem.unique.word }
end
Then in your tests create words as you need. Here I'm using RSpec.
let(:dictionary) { create(:dictionary) }
let!(:words) { create_list(:dictionary_word, 3, dictionary: dictionary) }
context 'when the word is in the dictionary' do
let(:word) { words.sample }
it 'finds the word' do
expect( dictionary.exists?(word) ).to be_truthy
end
end
context 'when the word is not in the dictionary' do
let(:word) { "septemburary" }
it 'does not find the word' do
expect( dictionary.exists?(word) ).to be_falsey
end
end
And if you need more words for manual testing, open a console and make some.
[1] pry(main)> FactoryBot.create_list(:dictionary_words, 100)
This is not particularly efficient, but you probably don't really need 180,000 words.
Ruby on Rails - seed from development database
You could use a gem such as https://github.com/rroblak/seed_dump to dump the selected table then on the production server run RAILS_ENV=production rake db:seed
to seed the data.
rake db:seed:dump MODELS=cities APPEND=true
looks like the command you need to run to dump the data out into a seed file.
Otherwise you could export the database table as a MySQL dump and import it into the production database.
How to seed the database after deployment with user input?
I got stuck there for long time without any solution.
Then I solved the problem be adding these information manually on my production database. So that I don't need to enter any thing while seeding.
For other seed files, I just call
cap production rails:rake:db:seed
Which seeds all files saved in production directory.
I hope this workaround solution could help someone.
Rails - In-app database seed button?
You can simply use Rails.application.load_seed
where you want in your code
How do I create a seed file using a model with references? I'm not sure I set up the models correctly
Hardcoding ids is not a good practice (even when your db is empty - new record is not guaranteed to have id 1),
In your seeds - pass objects, like:
lana = User.create(user_name: "Lana", email: "lanagrebnova@gmail.com", password: "bony2015", street_address: "15 Schley Rd.", city: "Far Hills", state: "NJ", balance: 25 )
burrito = Item.create(name: "burrito", price: 8, vendor: lana)
How to seed Rails db with images from the asset pipeline (paperclip)?
Public Images
If you are referencing an image in the public folder, store the root-relative path to the image as a string
in the database. (E.g., if your image file is project/public/images/pic.jpg
, then you would have image: '/images/pic.jpg'
in the seeds.
Asset Managed Images
If you are referencing an image in your assets, things can get a touch more complicated (unless you’ve ill-advisedly turned off the config.assets.digest
config). You’ll want to use the path to the asset in the seeds file (like with the first part of this answer referencing files in the public folder), but then when you want to link to the image in your views you’ll have to use Rails’ image_tag
to get the asset-managed url for the image.
If for some reason you want to be able to get the asset-managed path to the image in any way other than image_tag
in views, it gets a bit complicated. You can find some more details on working with the asset pipeline in the official Rails guide to The Asset Pipeline.
Images stored in Database
If you are storing the image file data in the database, you would use a binary
field (not string
). You could load the image data with a call to File.read
. E.g.:
image_data = File.read('path/to/image.jpg')
Model.create!([
{
...
image: image_data
},
...
])
You’ll need to add a custom controller method & route to deliver the image data as a file to the client (be sure to handle the mime type correctly for that).
Personally, in those cases where I’ve chosen to store raw file data in the database, I prefer to have a separate table just for the data and then join it to the main model as needed. (In this case, there would be your existing images
table, and it would be joined to a table named something like image_files
with just one field, aside from id
):
create_table :image_files do |t|
t.binary :data
end
And then you could reference that from your images
table:
t.belongs_to :image_file
(or put the reference to the images
table in the image_files
table.)
As to the arguments for/against storing raw file data in a database, in general it’s sub-optimal (you lose the benefits of having the web-server directly sending the files from the filesystem and have to have Rails intervene). But it can make sense in some cases (such as when you want to restrict access — e.g., to specific users).
How do I seed my database with only part of my seed code?
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
How to seed my development database with rails test fixtures
You can trigger the load of your fixtures in your database by using the following rake command:
rake db:fixtures:load
By default, the rails env will be development so the fixtures will load in this environment's database.
Related Topics
Find Out If Current Time Is Between Two Times
To_D to Always Return 2 Decimals Places in Ruby
How to Sum Array of Numbers in Ruby
How to Reload the Current Page in Ruby on Rails
Validation for Non-Negative Integers and Decimal Values
Ruby Class Instance Variable Vs. Class Variable
How to Write a Switch Statement in Ruby
Cannot Load Such File - Zlib Even After Using Rvm Pkg Install Zlib
Is Ruby Pass by Reference or by Value
Why Do Ruby Setters Need "Self." Qualification Within the Class
How to Dynamically Create a Local Variable
Rails 4: List of Available Datatypes
Ruby 1.9: Invalid Byte Sequence in Utf-8
How to Convert a String Object into a Hash Object