Generating PDF with Ruby on Rails

Example app

For a quick view of a PDFMonkey integration, we created a demo Rails application you can inspect.

Installing the pdfmonkey gem

Add the pdfmonkey gem to your project’s Gemfile:

gem 'pdfmonkey'

Authentication

Start by retreiving your private API key in the My Account page of the dashboard.

Once you obtained your key, you can choose between two options when it comes to authentication.

This option can be very useful when hosting on a platform like Heroku or using a container like Docker.

Simply set the PDFMONKEY_PRIVATE_KEY environment variable and you’re done.

heroku config:set PDFMONKEY_PRIVATE_KEY=YOUR-API-KEY -a YOUR-APP
docker run --env PDFMONKEY_PRIVATE_KEY=YOUR-API-KEY ...
PDFMONKEY_PRIVATE_KEY=YOUR-API-KEY
PDFMONKEY_PRIVATE_KEY=YOUR-API-KEY bundle exec rails s

Using an initializer

Alternatively you can use a Rails initializer to set your API key:

# config/initializers/pdfmonkey.rb

Pdfmonkey.configure do |config|
  config.private_key = 'YOUR-API-KEY'
end

Generate a document

Let’s take the example of a contract in your application.

If you want to create a new PDF when the contract is modified, use an after_commit callback:

# app/models/contract.rb

# Table contracts
# client_name     String
# client_address  String
# service_fee     Integer
# pdfmonkey_id    String
class Contract < ApplicationRecord
  DOCUMENT_TEMPLATE_ID='YOUR-TEMPLATE-ID'

  after_commit :generate_pdf

  private

  def generate_pdf
    # Don’t run this callback if the pdfmonkey_id is updated
    return if previous_changes.key?('pdfmonkey_id')

    # Retreive the data you want to send to generate your document
    dynamic_data = attributes.slice('client_name', 'client_address', 'service_fee')

    # Generate the document and wait for it to be generated
    pdfmonkey_doc = Pdfmonkey::Document.generate!(DOCUMENT_TEMPLATE_ID, dynamic_data)

    if pdfmonkey_doc.status == 'success'
      # Update the PDFMonkey document id stored in the contract
      update(pdfmonkey_id: pdfmonkey_doc.id)
    else
      # Handle cases where the document failed for some reason
    end
  end
end

Now that a document is generated everytime a Contract is modified, let’s add a download link in our app.

Everytime you fetch a document from PDFMonkey, we provide a download URL. This URL is valid for 30 seconds.

This means that you can choose to store the document yourself or fetch a new URL for every click. In this cookbook we’ll do the later.

# config/routes.rb
resources :contract_documents, only: [:show]

# app/controllers/contract_documents_controller.rb
class ContractDocumentsController < ApplicationController
  def show
    contract = Contract.find(params[:id])
    document = Pdfmonkey::Document.fetch(contract.pdfmonkey_id)

    redirect_to document.download_url
  end
end

You can then add a simple link in a view:

<%= link_to 'Download', contract_document_path(@contract), target: '_blank' %>