I have a few parts of the solution, but I'm having trouble bringing them together.
I have a page with two text fields (in a form_tag) in which I'll enter a datetime string with the start and end dates of the records I want to download in CSV form.
I can use a submit_tag and get the two dates, but then I don't know how to get the view to tell the controller that I want a CSV, so . I can use a link_to, but then the params get left behind.
The view and controller look a little wonky as I'm trying to figure out how this stuff should work together. I won't ship both a link and a button, for example. I also removed/changed things as needed for brevity/privacy.
show.html.erb:
<%= form_tag do %>
<br/><br/>
<%= label_tag :start_date, "From:" %>
<%= text_field_tag :start_date, nil, size: 40 %>
<%= label_tag :end_date, "To:" %>
<%= text_field_tag :end_date, nil, size: 40 %>
<br/>
<%= link_to "Export Report", report_path(:csv) %>
<%= submit_tag("Generate .CSV", format: :csv) %><br/><br/>
<% end %>
report_controller.rb:
require 'csv'
class ReportController < ApplicationController
def show
if params[:start_date]
@data = get_data(params[:start_date], params[:end_date])
respond_to do |format|
format.html
format.csv
end
end
end
def build_csv_enumerator(header, data)
Enumerator.new do |y|
CSVBuilder.new(header, data, y)
end
end
def download
if params[:start_date]
@data = get_data(params[:start_date], params[:end_date])
respond_to do |format|
format.html
format.csv
end
end
redirect_to action: "show"
end
private def csv_filename
"report-#{Time.now.to_s}.csv"
end
end
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
download.csv.erb:
<%- headers = ["name", "email", "created_at"] -%>
<%= CSV.generate_line(headers) %>
<%- @data.each do |line| -%>
<%- row = line.values_at(*headers) -%>
<%= CSV.generate_line(row) %>
<%- end -%>