Returning CSV data to the browser - revisited

Auteur: 
François Beausoleil

Back in 2006, I wrote Returning CSV data to the browser. The method I was using back then is way obsolete. Let’s use the correct way to do it. If you want to follow along, just browse over to returning-csv-data-to-the-browser-revisited and read on.

First of all, the correct way to return non HTML data to the browser is to use respond_to. Let’s do so here:

app/controllers/reports/timelines_controller.rb

1 class Reports::TimelinesController < ApplicationController
2 def show
3 @timelines = Timeline.all
4 respond_to do |format|
5 format.csv do
6 response.headers["Content-Type"] = "text/csv; charset=UTF-8; header=present"
7 response.headers["Content-Disposition"] = "attachment; filename=timeline-report.csv"
8 end
9 end
10 end
11 end

The rest is pretty easy. Generating the data is easy enough:

app/models/timeline.rb

1 require "fastercsv"
2
3 class Timeline < ActiveRecord::Base
4 default_scope :order => "started_at ASC"
5
6 def to_csv
7 FasterCSV.generate_line([
8 started_at.to_s(:db),
9 ended_at.to_s(:db),
10 project_id]).chomp
11 end
12 end

And rendering the view? Look how easy this gets:

app/views/reports/timelines/show.csv.erb

1 Started At,Ended At,Project ID
2 <%= render :partial => @timelines %>

Notice the file’s name? show.csv.erb? The csv in the filename is what connects the respond_to call with the view.

And the final piece, the timeline partial:

app/views/reports/timelines/_timeline.csv.erb

1 <%= timeline.to_csv %>
2

Now, on to the next obsolete article in the bunch…