Matt Weick
Matt Weick

Reputation: 332

Rails send_file rendering files as plain text on new page instead of browser downloading file

When send_file is called, it's sending the file to the browser, but the browser is dumping the contents as plain-text on a new page instead of downloading the file. If I refresh that page, it then downloads the file as normal.

Route

get 'download' => 'qr_codes#download'

Controller

def download
    path = Rails.root.join("events/active/#{params[:name]}/#{params[:batch]}/#{params[:file]}")
    send_file(path, type: 'application/vnd.ms-excel', filename: params[:file])
end

View

<%= link_to 'Original Upload', download_path(name: @event_name,
  batch: batch, file: batch_upload_filename(@event_name, batch)) %>

SOLUTION: This ended up being a known issue with turbolinks. If using Turbolinks 5 like I am, the updated syntax is: data: { turbolinks: false }

Upvotes: 3

Views: 1795

Answers (3)

Matt Weick
Matt Weick

Reputation: 332

This ended up being a known issue with turbolinks. If using Turbolinks 5 like I am, the updated syntax is:

data: { turbolinks: false }

Upvotes: 3

Usman Saleem
Usman Saleem

Reputation: 1

make helper method

def some_helper(content_type)
 Rack::Mime::MIME_TYPES.invert[content_type].gsub(/\./mi, '')
end

and update link as

<%= link_to 'Original Upload', download_path(name: @event_name, batch: batch, file: batch_upload_filename(@event_name, batch, format: file_format(attachment.file.content_type))) %>

Upvotes: 0

Andy Gauge
Andy Gauge

Reputation: 1428

Try setting the disposition:

def download
  path = Rails.root.join("events/active/#{params[:name]}/#{params[:batch]}/#{params[:file]}")
  send_file(path, type: 'application/vnd.ms-excel', filename: params[:file], disposition: 'attachment')
end

Or changing the file to ensure the extension is correct

"#{params[:file][0,params[:file].index(".")]}.xlsx"

Oh and don't inject params into a string to build routes for downloading. I can inject "../../" into :name, "config", into :batch, and "../config/database.yml" into :file. Add the file path to a model.

Upvotes: 1

Related Questions