19

I have a link_to Rails helper that downloads a wallpaper when clicked. But the image is loading in the browser instead of being downloaded immediately.

<%= link_to "1920x1080", @download.wallpapers[1].wallpaper.url %>

But at the same time I have a link_to Rails helper that downloads a screensaver of .exe format but here it works as inteded: file being downloaded immediately.

<%= link_to "720p", @download.screensavers.first.screensaver.url %>

What should I add or do so that the images will not be opened in the browser but instead be downloaded immediately?

Thanks!

neilmarion
  • 2,372
  • 7
  • 21
  • 36
  • 1
    Fairly certain this is a browser specific issue, not a web-framework issue. You can't view an EXE in a browser, but you can view an image. – Nick Radford Jul 20 '11 at 02:43

5 Answers5

43

There is an easier way to do this with the HTML5 download attribute.

<%= link_to 'Download existing avatar', @user.avatar(:original), download: "User_#{@user.id}_avatar" %>
amlutz160
  • 448
  • 5
  • 18
Abram
  • 39,950
  • 26
  • 134
  • 184
  • 4
    This should most definitely be the accepted answer now. – taylorthurlow Jul 27 '17 at 06:30
  • Is there a way to not change the filename and still add the download attribute? – Abhi Jan 27 '21 at 13:57
  • Yes, [according to the spec](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#attr-download) this attribute's value is optional - without it the browser will suggest a file name. – Matt Jul 25 '21 at 17:08
14

Instead of putting the link of the image in your tag, you can handle it in your controller. And then in your controller you can do something like

send_file @download.wallpapers[1].wallpaper.url, :type => 'image/jpeg', :disposition => 'attachment'

Read this

vinceh
  • 3,490
  • 1
  • 21
  • 24
  • For me it only worked with send_data: send_data image.url, :type => 'image/jpg', :disposition => 'attachment' being url a string " http:// url.com " for example – andre.orvalho Jan 30 '14 at 12:27
12

Generally, the cleanest way to do this is to set the appropriate header when sending the image:

Content-Disposition: attachment; filename=&lt;file name.ext&gt;

The send_file method will allow you to set this header appropriately if you're serving the file from the filesystem:

http://api.rubyonrails.org/classes/ActionController/Streaming.html#method-i-send_file

If the file is stored in your database, you can use send_data instead:

http://api.rubyonrails.org/classes/ActionController/Streaming.html#method-i-send_data

Sean McMains
  • 57,907
  • 13
  • 47
  • 54
8

Rails 3 / 4:

in routes:

get "home/download_pdf"

in controller:

def download_pdf
  send_file(
    "#{Rails.root}/public/your_file.pdf",
    filename: "your_custom_file_name.pdf",
    type: "application/pdf"
  )
end

in view:

<%= link_to 'Download PDF', home_download_pdf_url %>
rusllonrails
  • 5,586
  • 3
  • 34
  • 27
4

Here's a simple solution using the HTML5 download attribute with paperclip

<%= link_to item.name, item.asset.url, download: item.asset.original_filename %>
amlutz160
  • 448
  • 5
  • 18