Last active
February 2, 2022 23:52
-
-
Save diaz-de-berenguer/9e5b16837ad081c2c789898e003fc0e7 to your computer and use it in GitHub Desktop.
Integration of generating PDF using 'wicked_pdf' and uploading to AWS using 'aws-sdk'
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This Rails Model can be used to generate a PDF, upload to AWS, and store bucket/key | |
# of the PDF. Uses Wicked PDF and the AWS SDK. | |
# | |
# Gems: | |
# gem 'aws-sdk' # https://github.com/aws/aws-sdk-ruby | |
# gem 'wicked_pdf' # https://github.com/mileszs/wicked_pdf | |
# | |
# Sources: | |
# https://github.com/thoughtbot/paperclip/wiki/PDF-Email-Attachments-with-Paperclip-and-wicked_pdf | |
# https://gist.github.com/micahroberson/5988843 | |
class PdfFile < ApplicationRecord | |
# START HERE: | |
# Validation is used to trigger the upload. If the PDF upload fails, this model will | |
# not be saved to the Database. The order is important here, since the :key and :bucket | |
# values will be set by the :upload_to_s3_and_validate_response method. | |
validate :upload_to_s3_and_validate_response, :on => :create | |
validates_presence_of :key, :bucket | |
# For this model to work, the bucket must be set up on S3. You must have an AWS account | |
# and have it linked to your Rails App. More info here: | |
# http://docs.aws.amazon.com/sdk-for-ruby/v2/developer-guide/setup-config.html | |
def bucket_name | |
return "your-bucket-name" | |
end | |
# Uploads the PDF to the AWS bucket, returns a response. | |
def upload_to_s3 | |
# Set Buket and Key | |
filename = "#{self.id}-#{Time.now.strftime('%Y%m%d%H%M%S')}.pdf" | |
self.key = "pdf/#{filename}" | |
self.bucket = bucket_name | |
# Get path for generated PDF. This is performed by the :create_pdf_path method. | |
pdf_path = create_pdf_path | |
# Open temp file | |
pdf = File.open(pdf_path) | |
# Upload to AWS | |
s3 = Aws::S3::Client.new | |
response = s3.put_object( | |
bucket: self.bucket, | |
key: self.key, | |
body: pdf, | |
acl: "public-read" # optional: makes the file readable by anyone | |
) | |
# Remove Temp file after upload | |
File.delete(pdf_path) if File.exist?(pdf_path) | |
return response | |
end | |
# Generates the PDF from a view and returns a path to the Temp File where the PDF is | |
# currently located. This path is used by the :upload_to_s3 method to perform upload. | |
def create_pdf_path | |
# use wicked_pdf gem to create a PDF from an html template. | |
doc_pdf = WickedPdf.new.pdf_from_string( | |
ActionController::Base.new().render_to_string( | |
template: "pdfs/show", # <- this is the location of the PDF template. | |
layout: "layouts/pdf.html.erb", # <- layout used for PDF files. | |
locals: { x: "example" } # <- any local variables in template. | |
), | |
pdf: "Document Name", | |
page_size: "Letter", | |
orientation: "Landscape", | |
margin: { top: "0.5in", | |
bottom: "0.5in", | |
left: "0.5in", | |
right: "0.5in" }, | |
disposition: "attachment" | |
) | |
pdf_path = Rails.root.join("tmp", "temp_pdf_file_#{self.id}_#{Date.today.iso8601}.pdf") | |
File.open(pdf_path, "wb") do |file| | |
file << doc_pdf | |
end | |
# Returns the path of the temporary PDF file. eg: "/tmp/temp_pdf_file_132_2017-12-12.pdf" | |
return pdf_path | |
end | |
private | |
# This validation generates the PDF, performs the upload, and makes sure that it | |
# was all done succesfully. | |
def upload_to_s3_and_validate_response | |
response = self.upload_to_s3 | |
self.errors.add :base, "unable upload PDF" if response.error.present? | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment