Skip to content

Instantly share code, notes, and snippets.

@diaz-de-berenguer
Last active February 2, 2022 23:52
Show Gist options
  • Save diaz-de-berenguer/9e5b16837ad081c2c789898e003fc0e7 to your computer and use it in GitHub Desktop.
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 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