Rails: Import Export CSV Data without Gem
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 }
endroot ‘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
enddef 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 !