Download pdf instead of showing it in the browser - ruby-on-rails

I am using pdfkit on my rails application (I did this according to Ryan Bates railscast)
Currently it's showing the pdf inside the browser.
How can the pdf be downloaded instead ?
Thanks
EDIT:
Thanks for the response!
But how can I create the data of the pdf in the controller?
The pdf shows up automatically when the url has .pdf. for example when going to this link:
http://localhost:3000/home/index.pdf
It opens a pdf version of the the page automatically on the browser (it's a rails middleware setup).

Try using the send_data method that all rails controllers have.
Something like this:
# Generate a PDF document with information on the client and return it.
# The user will get the PDF as a file download.
def download_pdf
send_data(generate_pdf, :filename => "my_file.pdf", :type => "application/pdf")
end

Assuming it a simple rack end point:
class PdfEndpoint
def call(env)
[200, {"Content-Type" => "application/pdf", "Content-Disposition" => "attachment", "filename" => "filename.pdf"}, pdf_data]
end
end
Also the following Railscast will probably help:
http://railscasts.com/episodes/151-rack-middleware

Related

Rails download http response/displayed site

Instead of displaying the xml file rendered by the index.api.rsb file in my browser, i want to download it. To me this sounds very simple, but I cant find a solution.
I tried the following in the controller-method:
def split
if params[:export] == "yes"
send_file *here comes the path to xml view*, :filename => "filename", :type => :xml
end
respond_to ...
end
The result is a MissingFile exception...
Thanks in advance
Note that :disposition for send_file defaults to 'attachment', so that shouldn't be a problem.
If you have a MissingFile exception, that means the path is incorrect. send_file expects the path to an actual file, not a view that needs to be rendered.
For your case, render_to_string might be what you need. Refer to this related question. It renders the view and returns a string instead of setting the response body.
def split
if params[:export] == "yes"
send_data(render_to_string path_to_view, filename: "object.xml", type: :xml)
end
end
To force it to download it, add :disposition => attachment to your send_file method.
Source: Force a link to download an MP3 rather than play it?

When using redirect_to files on s3. How to either display an image or download a file

In Rails 3 AttachmentsController, I have the following:
def show
attachment = Attachment.find_by_id(params[:id])
redirect_to(attachment.authenticated_url())
end
Where authenticated_url is simply a URL to S3 to access the file.
The problem is that the file is always downloaded by the browser. What I would like to have happen is if the file is an image/pdf, something the browser can render, show the file in the browser and only download non-browser friendly files.
Have you seen this before? Any ideas on where to start?
Thanks
send_file can be used for remote url as well
file = open("http://cdn2.example.com/somefile.pdf")
send_file(file, :filename => "example.pdf", :type => "application/pdf" , :disposition => "attachment")
Here example.pdf will be downloaded. If you want open pdf in browser itself use this
file = open("http://cdn2.example.com/somefile.pdf")
send_file(file, :filename => "example.pdf", :type => "application/pdf" , :disposition => "inline")
redirect_to #attachment.url
I'm using Paperclip as well, and this display pictures inside the browser. Do you have to do something different than this?
I think you'll want to look into the rails send_file method.
1) http://apidock.com/rails/ActionController/DataStreaming/send_file
The :disposition option lets you decide whether a file will be downloaded or displayed inline. I used this in my rails app to let users download mp3 files.
Hope this helps.

Download Image attached using Paperclip

Is there a way to make the users download the images attached using paperclip?
I just made a link like this:
link_to 'imagename', image.attachment.url
But this makes the browser open the image. I want the browser to ask the user to save the image. Is there a way to do that?
When it comes to sending a file you can find all information in here http://api.rubyonrails.org/classes/ActionController/Streaming.html There are most important cuts:
Simple download:
send_file '/path/to.zip'
Show a JPEG in the browser:
send_file '/path/to.jpeg', :type => 'image/jpeg', :disposition => 'inline'
Show a 404 page in the browser:
send_file '/path/to/404.html', :type => 'text/html; charset=utf-8', :status => 404
to use one of this option you have to create a new action in controller like this:
class SomeController < ApplicationController
def download_file
send_file image.attachment.path
end
end
Here's a simple solution using the HTML5 download attribute
<%= link_to image.name, image.attachment.url, download: image.attachment.original_filename %>

Saving XML files with Rails

im working on a Rails project that should create XMl files, or to be more specific
use existing XMl templates and put content from the database in it.
So i dont need to create the xml structure, basically just rendering a template with content.
What would be the smartest way to do that?
So far i have a file.xml.erb in my layout folder
and i have a custom route "/renderXML" that does
def renderXML
#reading_question = ReadingQuestion.find(params[:id])
render :file => 'layouts/question.xml'
end
This works, but i also want to save the file, not only show it (actually viewing it is not really needed).
For saving i found this
File.open('fixed.xml','w'){|f| f.write builder.to_xml}
How do i access the rendered file and save it with some method like above?
Perhaps something like:
s = render_to_string :file => 'layouts/question.xml'
File.open('fixed.xml','w'){|f| f.write s}
render :text => s
Another approach :
send_data fixed, :type => 'text/xml; charset=UTF-8;', :disposition =>
"attachment; filename=fixed.xml"

Prawn PDF with Rails mailer?

I have successfully created an email that sends on creation of a Kase, but now I need to attach a PDF that is created on the fly by Prawn and Prawno. Basically when you visit a kase such as application.com/kase/1 you just append the URL with .pdf i.e. application.com/kase/1.
I spent ages getting the PDF to work and look how I wanted, but I can't figure out how to add the PDF to an auto sending email - mainly because I cannot work out how to give it a link as it's auto generated.
Has anyone ever managed to get this to work?
Thanks,
Danny
I suppose it would be better if you store generated pdf somewhere - for caching purposes, etc.
But with current configuration, you can read generated page with Net::HTTP and attach response:
require 'net/http'
def your_mailer_method(record)
#...
attachment "application/pdf" do |a|
a.body = Net::HTTP.get('yourdomain.com', "/kase/#{record.id}.pdf")
a.filename="your_pdf_name.pdf"
end
end
You really should consider just not using Prawnto, and creating a subclass of Prawn::Document to do what you need. Then, in both your controller and your mailer code, it should just be:
MyReport.new.render
See the Prawn documentation on this:
http://wiki.github.com/sandal/prawn/using-prawn-in-rails
For the newer ones, you dont really need to send a request again, when you can ::
mail.attachments["invoice.pdf"] = {:mime_type => "application/pdf" , :content => pdf_generator}
Instead of doing this ::
send_data pdf.render , :filename => file_name_here , :type => "application/pdf"
just do this ::
pdf.render , :filename => file_name_here , :type => "application/pdf"
Do not send_data, just render that pdf in your email attachment as mentioned in the first snippet.
In fact, i just wrote a Gist on github.
This code works for me
def send_file(file, subject, text, to_email)
#subject = subject
#text = text
attachments["#{invoice.invoice_number}.pdf"] = file
from_email = abc#xyz.com
mail(:to => to_email, :from => from_email, :subject=> subject)
end

Resources