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…