In this guide we'll walk through how to add seed data from a CSV file to your Rails application.
In your Gemfile
add:
gem 'seed-fu', '~> 2.3', '>= 2.3.9'
Run bundle install
Each seed file can be used to represent a single Model. For example, if you want to import seed data for your Keywords model, create a csv named seed_keywords.csv
.
In your .csv file, add headers in the first row. For example, your headers can be id
, title
, description
.
Add your .csv file to the fixtures folder: my_app/db/fixtures/seed_keywords.csv
.
Open rails console
and paste in the following:
require 'csv'
require 'seed-fu'
#change these to match the seeded model
@csv_file = 'db/fixtures/seed_keywords.csv'
@output_file = 'db/fixtures/seed_keywords.rb'
@class_name = 'Keyword'
@seeds = CSV.read("#{@csv_file}", { headers: true } )
SeedFu::Writer.write("#{@output_file}", :class_name => "#{@class_name}", :constraints => [:id]) do |writer|
@seeds.each do |seed|
hash = {}
@seeds.headers.reject{|h| h.nil?}.each do |header|
hash[header.to_sym] = seed[header]
end
writer.add(hash)
end
end
This will generate a seed file named db/fixtures/seed_keywords.rb
. The seed file should look similar to this:
Keyword.seed(:id,
{:id=>"1", :title=>"keyword one", :description=>"description one"}
{:id=>"2", :title=>"keyword two", :description=>"description two"}
{:id=>"3", :title=>"keyword three", :description=>"description three"}
)
We're going to assume you're using capistrano for your deployments. Open your config/deploy.rb
file and at the bottom add:
# To seed on local run `rake db:seed_fu`
# To seed on production run `cap production db:seed_fu`
require 'seed-fu/capistrano3'
To seed on local run rake db:seed_fu
To seed on production run cap production db:seed_fu
Afterwards, run rails console
and check the values in Keyword.first
to see if the data was seeded correctly.
Sometimes after you import records when you try to create a record you get a unique constraint error based off the table's primary key id not increment based off the latest id. To resolve this, you should reset the primary key sequence which Postgres uses. For example, if you have 3513 records imported, the next record created should have an ID of 3514.
ActiveRecord::Base.connection.reset_pk_sequence!('table_name')