67

I would like to give visitors the option to download some pdf. I have tried:

<%= link_to "abc", "/data/abc.pdf"%>

<%= link_to "abc", "/data/abc.pdf", :format => 'pdf' %>

and some variations but they don't seem to work. I keep getting No route matches [GET] "/data/abc.pdf"

I have the pdf files in a folder called data, located in the assets folder. Any help would be appreciated.

felipeclopes
  • 4,010
  • 2
  • 25
  • 35
Ionut Hulub
  • 6,180
  • 5
  • 26
  • 55

6 Answers6

89

Rails 4:

in routes:

get "home/download_pdf"

in controller (already have pdf):

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

in controller (need to generate pdf):

require "prawn"
class ClientsController < ApplicationController

  def download_pdf
    client = Client.find(params[:id])
    send_data generate_pdf(client),
              filename: "#{client.name}.pdf",
              type: "application/pdf"
  end

  private

  def generate_pdf(client)
    Prawn::Document.new do
      text client.name, align: :center
      text "Address: #{client.address}"
      text "Email: #{client.email}"
    end.render
  end
end

in view:

<%= link_to 'Download PDF', home_download_pdf_url %>

Rails 3

The way to do it:

def download
  send_data pdf,
    :filename => "abc.pdf",
    :type => "application/pdf"
end

You should go to this alternative

Rails < 3

File in public folder

This may the the answer to you: How to download a file from rails application

You should place your file in public folder, that is the trick.

Should work when the file is placed correctly.

Let me know if you can't move your file to public folder.

Download via controller

Create a controller with a downlaod action and link_to it

  def download
    send_file '/assets/data/abc.pdf', :type=>"application/pdf", :x_sendfile=>true
  end
felipeclopes
  • 4,010
  • 2
  • 25
  • 35
  • that's an old version of rails. since rails 3 (I think) the public folder is assets. – Ionut Hulub Oct 31 '12 at 18:16
  • ok I tried that and it worked. I'm pretty sure all resources should be placed in the assets folder since rails 3 but since it worked it will do for now. thank you. – Ionut Hulub Oct 31 '12 at 18:18
  • Sorry it was not specified which version of rails you were using – felipeclopes Oct 31 '12 at 18:19
  • Check the new edit I just made for Rails 3. Hope it helps you! – felipeclopes Oct 31 '12 at 18:22
  • No need for this approach if those pdf's are available to everyone. With Rails 3.1 js, css and images are moved to assets folders (because of precompiling) but public folder has it's purpose still, like this one :) – BurmajaM Jan 23 '13 at 22:20
78

Rails 4:

in routes:

get "home/download_pdf"

in controller (already have pdf):

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

in controller (need to generate pdf):

require "prawn"
class ClientsController < ApplicationController

  def download_pdf
    client = Client.find(params[:id])
    send_data generate_pdf(client),
              filename: "#{client.name}.pdf",
              type: "application/pdf"
  end

  private

  def generate_pdf(client)
    Prawn::Document.new do
      text client.name, align: :center
      text "Address: #{client.address}"
      text "Email: #{client.email}"
    end.render
  end
end

in view:

<%= link_to 'Download PDF', home_download_pdf_url %>
rusllonrails
  • 5,586
  • 3
  • 34
  • 27
  • 2
    just use <%= link_to "Download Pdf", "files/pdf.pdf", :class => "themed_text" %> – Navin Apr 16 '14 at 06:25
  • the advantage of using the route url is that if the file is generated as a tempfile inline, you don't rely on a specific filename/path to the file. – jaydel Aug 27 '14 at 11:11
  • to further clarify, I understand that isn't the OP's question, but it's a more generalize answer – jaydel Aug 27 '14 at 11:12
  • @Navi I tried your approach but I keep getting the No route matches error. My directory is /assets/templates/ and is listed when I use Rails.application.config.assets.paths in the console but is not listed in my public folder. Can you see the issue here? – Marklar Jul 14 '15 at 00:38
  • How would you adjust this for multiple files? IE a folder of files one was generating links to in a list – Btuman Apr 14 '16 at 21:22
  • Is this the same for rails 5 ? – stevec May 25 '19 at 03:08
25

If the files are static (meaning they don't change), place them in the public folder.

Then you can download like

<a href="file.pdf" download>PDF</a>

or with ERB

<%= link_to 'PDF', 'file.pdf', download: '' %>

and to give the file another name for downloading, just pass that name to the download option

<%= link_to 'PDF', 'file.pdf', download: 'data' %>

This will download the file as data.pdf instead of file.pdf.

Cruz Nunez
  • 2,949
  • 1
  • 23
  • 33
4

you can simply call your controller action like this

<%= link_to "Download", download_file_path, class: "btn btn-sm btn-default", target: "_blank" %>

and in your controller

def download_file
 redirect_to paperclip_attachment.file.url
end
  • this is a rails project so you'd want to use the `link_to` helper – daslicious Aug 17 '16 at 21:53
  • Is this suggestion leads to down voting the answer or just to say poster to update his/her the answer? I think this attitude is not right for newbie SO users like me. – Muhammad Nasir Shamshad Aug 18 '16 at 13:58
  • only the attitude you imagine. just trying to help the newbie. the question uses the helper as well, which is a better reason to use it in your answer – daslicious Aug 19 '16 at 00:57
1

I Struggle a lot to find simple way to Auto Downlaod Some File From Public Directory. Finally i come up with this solution. For Example: i Have my file in SVG folder inside Public Directory.

Public/svg/Test1.xlsx

Now When i try to Access it load it and Give Path with Paper clip it give issue. Even When i try full path it give issue as well so we can make it dynamic path. First Get Path of the Host so that Can Redirect Easily. <% url = request.original_url.chomp(request.fullpath) %>

Now we Can Access any file in Public Folder Like below and Pass id and Download option. Download option rename any file which u want to download.

<%= link_to 'Database File', "#{url}/svgs/Test1.xlsx", download: 'Data.xlsx',id: "Link_to_Downlaod" %>

Now Click able link is Ready We Can Click on Above link to Download the File. Use the Following Script to Auto Download the File.

  <script type="text/javascript">
    window.onload = document.getElementById('Link_to_Downlaod').click();
  </script>
</div>

For the Case of PDF or any Any other file type just need to change the file extension.

1

For me the best solution to link to a pdf file is by these simple steps:

1- Add your pdf file inside the public folder

2- <%= link_to "/nameofthefile.pdf",target: "_blank" do %>pdf file<% end %>

Here is a video to show you this in detail https://www.youtube.com/watch?v=bNZ6FJrZ_lo&t=64s`

Jai Chauhan
  • 4,035
  • 3
  • 36
  • 62
nourza
  • 2,215
  • 2
  • 16
  • 42