How to Seed a Database in Rails

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



Leave a reply



Submit