Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3 - set the filename in a respond_to

This seems like it should be simple, but I can't seem to find a straight answer.

I have added a csv mime-type, and the following seems to work, except that the downloaded file is always named "report.csv".

In my controller:

def report
  respond_to do |format|
    format.html
    format.csv do
      render :template => "summary/report.csv.erb",
             :filename => "foo" #doesn't work
    end
  end
end

I think it's using the default renderer (I haven't implemented an alternate renderer), but I can't seem to find complete docs on the options available.

Isn't there something like a "filename" option or something that I can use? Is there a better approach?

like image 774
Grant Birchmeier Avatar asked Oct 15 '12 18:10

Grant Birchmeier


3 Answers

I got it, thanks to some help from this answer.

format.csv do
  response.headers['Content-Disposition'] = 'attachment; filename="' + filename + '.csv"'
  render "summary/report.csv.erb"
end

First you set the filename in the response header, then you call render.

(The template param to render is optional, but in my case I needed it.)

like image 152
Grant Birchmeier Avatar answered Nov 13 '22 13:11

Grant Birchmeier


You can pass the filename to send_data and let it handle the Content-Disposition header.

# config/initializers/csv_support.rb
ActionController::Renderers.add :csv do |csv, options|
  options = options.reverse_merge type: Mime::CSV
  content = csv.respond_to? :to_csv ? csv.to_csv : csv.to_s
  send_data content, options
end

# app/controllers/reports_controller.rb
respond_to do |format|
  format.html ...
  format.csv { render csv: my_report, filename: 'my_report.csv' }
end

Then add a to_csv method to my_report or pass a pre-generated CSV string.

like image 45
Flwyd Avatar answered Nov 13 '22 12:11

Flwyd


Alternatively you can use a combination of send_data and render_to_string (since you have a CSV template).

def report
  respond_to do |format|
    format.html
    format.csv do
      send_data render_to_string(:template => "summary/report.csv.erb"),
             :filename => "foo"
    end
  end
end
like image 33
Slobodan Kovacevic Avatar answered Nov 13 '22 12:11

Slobodan Kovacevic