Rails: Import Export CSV Data without Gem

Kartik Jagdale
coderaga
Published in
2 min readNov 19, 2016

Hi Folks,
Recently I was assigned a task to make changes to Rails Admin. So I looked into it and started playing with it and exploring its feature.
I was kinda impressed with one feature of exporting the records in CSV format.

I wanted to give it a try and make my own without using a gem.

Now I knew there was a csv library for ruby. So I started with this library and made a feature for exporting and importing csv files without using gem(though I know I am using a CSV, a inbuilt feature of ruby, then probably i just wanted to see how it works).

CSV Library Doc : http://ruby-doc.org/stdlib-2.0.0/libdoc/csv/rdoc/CSV.html

So, I started by making this example app which has a model Movie and its details.

Source : https://github.com/coderaga/RailsTutos/tree/master/Import-Export-CSV-Data

Code Summary :

#!config/application.rb
require ‘csv’

Now the Routes..

#! routes.rbresources :movies do
collection { post :import }
end
root ‘movies#index’

Now the Controller’s

#!movies_controller.rb
def index
@movies = Movie.all
respond_to do |format|
format.html
format.csv { send_data @movies
.to_csv([‘title’,
‘description’,
‘release_date’,
‘genre’,
‘runtime’,
‘rating’]
)
}
end
end
def import
Movie.import(params[:file])
redirect_to root_url, notice: ‘Movies Uploaded successfully’
end

Now the main part.. Model and the CSV logic.

#!movie.rb# == Schema Information
#
# Table name: movies
#
# id :integer not null, primary key
# title :string default(“”)
# description :string default(“”)
# rating :integer default(0)
# release_date :date
# genre :string default(“”)
# runtime :string
# created_at :datetime not null
# updated_at :datetime not null
#
class Movie < ActiveRecord::Base

# Generate a CSV File of All Movie Records
def self.to_csv(fields = column_names, options={})
CSV.generate(options) do |csv|
csv << fields
all.each do |movie|
csv << movie.attributes.values_at(*fields)
end
end
end
# Import CSV, Find or Create Movie by its title.
# Update the record.
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
movies_hash = row.to_hash
movie = find_or_create_by!(title: movies_hash[‘title’])
movie.update_attributes(movies_hash)
end
end
end

And finally showing it in views.

<! — app/views/movies/index.html.erb →<%=link_to ‘Export to CSV’, movies_path(format: ‘csv’)%><%= form_tag import_movies_path, multipart: true do%>
<%= file_field_tag :file %>
<%= submit_tag ‘Import CSV’%>
<% end %>

Thank you !

--

--