Giter VIP home page Giter VIP logo

Comments (11)

gaffneyc avatar gaffneyc commented on June 1, 2024 6

@westonganger Yeah, of course.

@renandhein That's exactly what I implemented a couple days ago on the cron job monitoring service I build (Dead Man's Snitch). I'll put the details here but I'll also open a PR (when I have a chance) to update the readme.

We have a route (get "/invoices/:id.pdf" => "invoices#show") for downloading invoices. You can use render_to_string("path/to/view", formats: [:pdf]) in your Mailer to render the PDF. For example, here is our Mailer code:

class BillingMailer < ApplicationMailer
  def send_invoice(invoice)
    @invoice = invoice

    filename = "dms-receipt-#{@invoice.created_at.to_date}.pdf"
    attachments[filename] = {
      mime_type: "application/pdf",
      content: render_to_string("invoices/show", formats: [:pdf]),
    }

    mail({ to: @invoice.emails, subject: "Monthly subscription paid" })
  end
end

from prawn-rails.

candland avatar candland commented on June 1, 2024 3

Another option for Rails 6, maybe 5.

ApplicationController.render(
  template: "shared/example",
  formats: [:pdf],
  assigns: { user: @user }
)

from prawn-rails.

westonganger avatar westonganger commented on June 1, 2024 1

@gaffneyc that is one way to do it. You can also manually save a PDF, I have done the following before:

### Load template to String
template = File.read('path/to/file.pdf.prawn')

### Initialize PrawnRails::Document, using normal prawn would be Prawn::Document
pdf_doc = PrawnRails::Document.new(page_size: 'A4', page_layout: :landscape, top_margin: 100)

pdf_doc.instance_eval do
  ### set any instances variables
  @items = Item.where(user_id: user_id)

  ### evaluate the template with your instance variables set above
  eval(template) 
end

### Render to file
pdf_doc.render_file('path/to/file.pdf')
# or
File.open('path/to/file.pdf', 'wb') do |f|
  f.write pdf_doc.render
end

Note: The template file must NOT contain prawn_document do .. end block. If you are using it in a Rails action as well and require this then you may need to do some massaging to exclude the prawn_document block. A ghetto example:

### Get template except first and last lines (which contain `prawn_document` block)
template = File.readlines('path/to/file.pdf.prawn')[1..-2].join 

Relying on first and last line is probably pretty fragile, your likely better off with a regex or something. Would love to hear a better recommendation.

from prawn-rails.

westonganger avatar westonganger commented on June 1, 2024

@gaffneyc can you comment on this? If so maybe you could also add a PR to the README.md that describes thisthis functionality? That'd be sweet.

from prawn-rails.

gaffneyc avatar gaffneyc commented on June 1, 2024

Sorry for the confusion, having a route isn't required. I mentioned it to show we were able to reuse the same logic both in the mailer and in our controller. render_to_string takes a path to a template that can be anywhere in app/views. For example, render_to_string("billing_mailer/invoice", formats: [:pdf]) would work if you only needed to render it for the mailer.

I prefer this approach as it allows us to leverage Rails's rendering pipeline and we're able to keep the views consistent across all of the places we may need to render the PDF. Having caveats like the view should not contain prawn_document only add to the complexity of using the view. I also avoid using eval as much as possible (instance_exec is often the safer option).

from prawn-rails.

renandhein avatar renandhein commented on June 1, 2024

@gaffneyc @westonganger Thank you so much to both of you for the help and inputs! I think both solutions are valid, though I did end up preferring the render_to_string solution as indeed it allows me to keep the view intact for both general rendering and mailer purposes.

I do have to point out though that using Rails 5.2 I wasn't able to use render_to_string inside a mailer due to render_to_string's internals calling methods that expect a controller environment (as far as I could tell). I had to fetch and build up the file contents in my controller before calling the mailer.

Still, render_to_string works beautifully and gets the job done. Creating a file as @westonganger suggested is a nice alternative, though.

Thank you so much!

from prawn-rails.

gaffneyc avatar gaffneyc commented on June 1, 2024

@renandhein Out of curiosity, did you get undefined method response for [MailerClass] or something similar?

from prawn-rails.

renandhein avatar renandhein commented on June 1, 2024

@gaffneyc Exactly! I did wonder if you ran into that while working on Dead Man's Snitch?

Awesome project by the way! I bookmarked it :)

from prawn-rails.

gaffneyc avatar gaffneyc commented on June 1, 2024

@renandhein I did actually, make sure you're on prawn-rails >= "1.2.0" as I recently fixed that in #30.

And thanks! I hope you find a use for it at some point :)

from prawn-rails.

renandhein avatar renandhein commented on June 1, 2024

@gaffneyc Thank you! Yeah, sorry about that, I am actually still at 1.0. I'll look into updating it and then things should work as you suggested.

Again, many thanks for all your support!

from prawn-rails.

westonganger avatar westonganger commented on June 1, 2024

Please ensure you are passing the :formats option as an array. Example:

ApplicationController.render(template: "shared/example", formats: [:pdf], assigns: { user: user })

from prawn-rails.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.