File Export
This article will guide you into creating a feature that exports our records into file with csv
and xml
formats.
Table of Contents
What is format?
Rails uses the format specified in the request and defaults to html
unless otherwise declared. You can change this by passing a symbol or an array to the formats
option.
What is CSV?
CSV is a shortened form for “Comma-Separated Values”. It’s a common data format made up of rows of values separated by commas. It is used to export and import data.
What is XML?
XML, or Extensible Markup Language, is a markup language and file format that can be used to store, transmit, and reconstruct arbitrary data. This programming language is used to define rules for encoding documents in a format that is both human-readable and machine-readable.
Export with CSV
By default, rails already have a csv library that can write and/or read csv. All we need to do is require csv
to include the library in file we are using the csv methods.
In our controller, create format for html and csv since we are dealing with both. Add the following to csv format:
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
# ...
+ require 'csv'
def index
@posts = Post.includes(:categories, :user).page(params[:page]).per(5)
+ respond_to do |format|
+ format.html
+ format.csv {
+ csv_string = CSV.generate do |csv|
+ csv << [
+ User.human_attribute_name(:email), Post.human_attribute_name(:id),
+ Post.human_attribute_name(:title), Post.human_attribute_name(:content),
+ Post.human_attribute_name(:categories), Post.human_attribute_name(:created_at)
+ ]
+
+ @posts.each do |p|
+ csv << [
+ p.user&.email, p.id, p.title, p.content,
+ p.categories.pluck(:name).join(','), p.created_at
+ ]
+ end
+ end
+ render plain: csv_string
+ }
+ end
end
# ...
end
The generate method wraps the provided string or an empty default string with a CSV object passed to the provided block. You can append csv rows to a string using a block. Afterwards, the last string is returned when the block ends.
Upon configuring the csv generator in our controller, next thing that we need to do is to add the export link to our posts index page.
<!-- app/views/posts/index.html. erb -->
<h1>Post List</h1>
+ <%= link_to 'Export', posts_path(format: :csv, page: params[:page]) %>
<table>
<!-- ... -->
Now we are done! When you click the Export
link, it will download your selected page post records in csv format.
Build XML
You can also build an xml file by using render xml
on your format xml.
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
# ...
def index
@posts = Post.includes(:categories, :user).page(params[:page]).per(5)
respond_to do |format|
format.html
+ format.xml { render xml: @posts.as_json }
format.csv {
# ...
}
end
end
# ...
end
We are now done with File Export.