Importing CSV into Rails

Joseph Harwood
2 min readMay 24, 2019

--

I had a code challenge for a company where I had to load a flat file of data from an Excel spreadsheet into a database. This is a quick guide to teach you how to load a CSV datatype file into your Rails backend.

First, create a table with the same number of columns and column names as the columns in your CSV.

Next, install the CSV gem:

gem install csv

In seeds.rb:

require 'csv'    filename = "YourFilePath"csv = CSV.parse(filename, :headers => true)
csv.each do |row|
YourTable.create!(row.to_hash)
end

This may be all that you need to do to get this to seed. I however hit the below errors and had to modify this.

`require’: no such file to load — iconv (LoadError)

The solution to this error stated in the StackOverflow post is to add this to your Gemfile and bundle install:

gem "iconv", "~> 1.0.3"

I also had to convert the hash keys to lowercase:

require 'csv'filename = "YourFilePath"CSV.foreach(filename, :headers => true) do |row|
new_hash = {}
row.to_hash.each_pair do |k,v|
new_hash.merge!({k.downcase => v})
end
YourTable.create!(new_hash)
end

The next error I got was:

ArgumentError: invalid byte sequence in UTF-8

The solution was to add:

CSV.foreach(file.path, headers: true, encoding:'iso-8859-1:utf-8') do |row|
...
end

The next roadblock was that the CORS Policy was blocking my requests. This StackOverflow post provides this solution:

1st Step: add gem to your Gemfile:

gem 'rack-cors', :require => 'rack/cors'

and then save and run bundle install

2nd Step: update your config/application.rb file by adding this:

config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*', :headers => :any, :methods => [:get, :post, :options]
end
end

Finally, my seeds.rb ended up looking like this and seeded successfully:

require 'csv'filename = "/Users/Joseph/Documents/restaurant_grades_sample.csv"CSV.foreach(filename, :headers => true, encoding:'iso-8859-1:utf-8') do |row|
new_hash = {}
row.to_hash.each_pair do |k,v|
new_hash.merge!({k.downcase => v})
end
Grade.create!(new_hash)
end

Sweet victory!

--

--

No responses yet