Stream CSV Files In Rails Because You Can

Using Rails and Ruby Enumerators to start sending data faster

Noel Rappin
Oct 5, 2016 · 5 min read
Image for post
Image for post
It’s a stream, kind of
class CsvBuilder

attr_accessor :output, :header, :data

def initialize(header, data, output = "")
@output = output
@header = header
@data = data
end

def build
output << CSV.generate_line(header)
data.each do |row|
output << CSV.generate_line(row)
end
output
end
end
def build_csv_enumerator(header, data)
Enumerator.new do |y|
CsvBuilder.new(header, data, y)
end
end
enum = build_csv_enumerator(header, data)
enum.next
enum.next
class ReportsController < ApplicationController

def show
respond_to do |format|
format.html \{\}
format.csv do
headers["X-Accel-Buffering"] = "no"
headers["Cache-Control"] = "no-cache"
headers["Content-Type"] = "text/csv; charset=utf-8"
headers["Content-Disposition"] =
%(attachment; filename="#{csv_filename}")
headers["Last-Modified"] = Time.zone.now.ctime.to_s
self.response_body = build_csv_enumerator(header, data)
end
end
end

private def csv_filename
"report-#{Time.zone.now.to_date.to_s(:default)}.csv"
end
end
def self.csv_collection
Model.find_each.lazy.map do |model|
model.to_row
end
end
build_csv_enumerator(header, Model.csv_collection)

Table XI

Tech Done Right

Noel Rappin

Written by

Noel Rappin is a Principle Software Engineer at Table XI. He is the author of Rails 5 Test Prescriptions and Take My Money: Accepting Payments on the Web.

Table XI

Table XI

Tech Done Right

Noel Rappin

Written by

Noel Rappin is a Principle Software Engineer at Table XI. He is the author of Rails 5 Test Prescriptions and Take My Money: Accepting Payments on the Web.

Table XI

Table XI

Tech Done Right

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store