Nicolas Raoul
Nicolas Raoul

Reputation: 60203

Rails: ZIP file shown in browser instead of being downloaded

My controller sends a ZIP file:

def index
  respond_to do |format|
    format.html  { render :text => open("tmp/test1.zip", "rb").read }
  end
end

PROBLEM: the ZIP is received as text shown in the browser.
I would like it to come as a download.

Note: I wrote format.html because when I write format.zip I get uninitialized constant Mime::ZIP. That is probably part of the problem.

Upvotes: 3

Views: 3705

Answers (4)

a simple solution for the user to download a file located in the application

def index
   send_data File.read('/full/path/to/tmp/test1.zip'), filename: "test1.zip"
end

send_data will read your file located here /full/path/to/tmp/test1.zip and then send it as a response as a file

and your user download a file with filename test1.zip

Upvotes: 0

vanyak
vanyak

Reputation: 156

You can register your own mime type:

Mime::Type.register "application/zip", :zip

def index
  respond_to do |format|
    format.html  { ... } #do whatever you need for html
    format.csv  { ... } #do whatever you need for csv
    format.zip  { send_file 'your_file.zip' }
  end
end

have a look here:

http://weblog.rubyonrails.org/2006/12/19/using-custom-mime-types

Upvotes: 10

mu is too short
mu is too short

Reputation: 434665

You can skip the respond_to stuff and manually set the content type:

def index
  render :file => '/full/path/to/tmp/test1.zip', :content_type => 'application/zip', :status => :ok
end

See the Layouts and Rendering in Rails guide for more information.

If you want to support .csv as well, then you could try looking at the params[:format]:

def index
  if params[:format] == 'zip'
    # send back the zip as above.
  elsif params[:format] == 'csv'
    # send back the CSV
  else
    # ...
  end
end

And have a look at send_file as Marian Theisen suggests.

Upvotes: 2

Related Questions