Comments (11)
@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.
Another option for Rails 6, maybe 5.
ApplicationController.render(
template: "shared/example",
formats: [:pdf],
assigns: { user: @user }
)
from prawn-rails.
@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.
@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.
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.
@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.
@renandhein Out of curiosity, did you get undefined method response for [MailerClass]
or something similar?
from prawn-rails.
@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.
@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.
@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.
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)
- Undefined Method HOT 3
- Please use semantic versioning HOT 2
- Couldn't change the filename using @filename HOT 5
- ActionController::UnknownFormat HOT 7
- Rendering of large PDF file: flush possible? HOT 1
- Possible missing step or error in README? HOT 5
- undefined method `headers' for nil after upgrading to v1.0.0 HOT 5
- Prawn::Emoji Support? HOT 8
- Add an option to control Content-Disposition HOT 8
- Is there any way to load pie chart using chartkiq in PDF HOT 1
- Load a custom ttf font HOT 10
- Bootstrap css import
- Rails 6: DEPRECATION WARNING: Single arity template handlers are deprecated. HOT 3
- Rails 6: Deprecation Warning: Single arity template handlers are deprecated. HOT 1
- Using with prawn-icon HOT 1
- DEPRECATION WARNING: Rendering actions with '.' in the name is deprecated HOT 5
- Release a new version on Rubygems HOT 2
- PrawnRails initializer doesn't get loaded HOT 7
- Issue running on Ruby 3.1 or 3.2 because official prawn gem hasnt released a new version. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from prawn-rails.