Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails download file from show action?

I have an uploader which allows you to upload documents. What I want to do is trigger a download for the document when you view its show action. The url would be something like:

/documents/16

This document could be .txt, or .doc.

So far, my show action looks like this:

  def show
    @document = Document.find(params[:id])
    respond_with(@document) do |format|
      format.html do
        render layout: false, text: @document.name
      end
    end
  end

How would I go about achieving this?

like image 970
Damien Roche Avatar asked Aug 19 '12 17:08

Damien Roche


2 Answers

Take a look at the send_data method:

Sends the given binary data to the browser. This method is similar to render :text => data, but also allows you to specify whether the browser should display the response as a file attachment (i.e. in a download dialog) or as inline data. You may also set the content type, the apparent file name, and other things.

So, I think in your case it should be something like this:

def show
  @document = Document.find(params[:id])
  send_data @document.file.read, filename: @document.name
end
like image 101
Mik Avatar answered Oct 24 '22 04:10

Mik


I created a new method in my controller for downloading a file. It looks like this. Stored_File is the name of the archived file and has a field called stored_file which is the name of the file. Using Carrierwave, if a user has the access/permissions to download the file, the URL will display and then send the file to the user using send_file.

Controller

 def download
    head(:not_found) and return if (stored_file = StoredFile.find_by_id(params[:id])).nil?

    case SEND_FILE_METHOD
      when :apache then send_file_options[:x_sendfile] = true
      when :nginx then head(:x_accel_redirect => path.gsub(Rails.root, ''), :content_type => send_file_options[:type]) and return
    end
    path = "/#{stored_file.stored_file}"

    send_file path, :x_sendfile=>true

  end

View

<%= link_to "Download", File.basename(f.stored_file.url) %>

Routes

match ":id/:basename.:extension.download", :controller => "stored_files", :action => "download", :conditions => { :method => :get }
like image 33
kobaltz Avatar answered Oct 24 '22 04:10

kobaltz