1

I'm trying to add a PDF download link on a blog I've created and am having trouble with the linking.

I consulted several SO posts (like this and this) to get as far as I have, but seeing as I'm working off variables (because I'm on blogs#show they only got me so far.

In my form, I have @blog.link_text for the exact link text that should show on the page (e.g. "Download a Free Printable PDF for Your Notes") and @blog.link_filename to store the path of the PDF that should be downloaded.

On blogs#show I have the following link in ERB:

  <h3>
    <%= link_to download_pdf_path(@blog.link_filename), type: "application/pdf" do %>
      <%= @blog.link_text %>
    <% end %>
  </h3>

Then in my routes.rb I have this:

  get "download_pdf", to: "blogs#download_pdf"

Finally, in my blogs_controller.rb I have the download_pdf method:

  def download_pdf(filename)
    send_file filename, type: "application/pdf"
  end

I currently have "app/assets/images/house_tour_notes.pdf" as the @blog.link_filename value, but I've tried a variety of other values. I currently have a copy of the PDF in images and in public.

The link appears properly on the page, but when it's clicked, I get:

No route matches [GET] "/download_pdf.%22app%2Fassets%2Fimages%2Fhouse_tour_notes.pdf%22"

Can anyone help troubleshoot this? Where am I going wrong?

Liz
  • 1,369
  • 2
  • 26
  • 61

1 Answers1

1

I think you can fix this easily by approaching it differently. The link could go to the blogpost itself:

<h3>
  <%= link_to download_pdf_path(@blog), type: "application/pdf" do %>
    <%= @blog.link_text %>
  <% end %>
</h3>

Change the route:

get "blogs/:id/download_pdf", controller: 'blogs', action:'download_pdf', as: 'download_pdf'

Then change the controller:

def download_pdf
  @blog = Blog.find(params[:id])
  send_file Rails.root.join(@blog.filename), type: "application/pdf"
end
bo-oz
  • 2,842
  • 2
  • 24
  • 44
  • This is definitely a great deal better than what I had! For some reason I'm still getting `Cannot read file "app/assets/images/house_tour_notes.pdf"`, even though I checked and the file was a valid PDF... – Liz Jun 03 '18 at 17:50
  • I updated the answer... it could be that it has to do with relative paths. I changed the controller to use `Rails.root.join(@blog.filename)`. If that doesn;t work, you might need to really open the file first. That would be: `File.new(Rails.root.join(@blog.filename))` – bo-oz Jun 03 '18 at 18:32
  • The last one works! Thank you so much for the help! – Liz Jun 03 '18 at 20:41
  • One more tip... you were trying to pass a file location as a parameter and return that file as a download. You should always ask yourself whether that could be misused... since the parameter can be easily manipulated, you are offering a way to download any file on your Webserver, not just the pdf you want to offer! That’s why it’s always better to only use record ID’s, so you have full control over what you are giving access to. – bo-oz Jun 04 '18 at 05:45