I have an index controller action which responds to the pdf format which looks something like
class ProposalsController < ApplicationController
respond_to :pdf, :html
def index
#proposals = Proposal.all
respond_with #proposals do |format|
format.html
format.pdf
end
end
end
Proposal has a to_pdf method which creates Prawn::Document. How can I loop over each of the propsals, grab it's PDF, append it to a newly created PDF, and then render that in the browser via respond_with?
One can use rails API to create a personalized renderer. In fact, the book Crafting Rails 4 Applications by José Valim show you how to create personalized PDF renderer in the first chapter.
Related
I have a Rails controller which provides both HTML and PDF responses, and thus I have view.pdf.haml and view.html.haml files. These are either identical or extremely close to identical.
How can I have Rails use a single view for multiple formats?
You can specify what format to render with :formats option:
# Both will render view.html.haml
respond_to do |format|
format.html { render :view }
format.pdf { render :view, formats: :html }
end
https://guides.rubyonrails.org/layouts_and_rendering.html#the-formats-option
Do you mean have the same action serve up different resource types - i.e. both a web page and a PDF? If I understand the problem, you can use the respond_to method.
def show
#object = Object.find params[:id]
respond_to do |format|
format.html
format.pdf { ..code to render the pdf.. }
end
end
That ..code to render the pdf.. is the tricky part. There are PDF gems that support inline rendering, but you may end up using send_data or similar to set a file name, disposition, etc and deliver the PDF document to the end user.
I am working with Wicked_PDF to generate pdf files for my application. Most examples normally have it generating based on a show page, but I want a link to get to a pdf for an index page.
Product Controller
def index
#search = Product.search(params[:q])
#products = #search.result.includes(:supplier, :prodcategory, :prodstatus)
respond_to do |format|
format.html
format.pdf do
render :pdf =>"product_report", :template => 'products/index.html.erb'
end
end
end
Product Index
<p><%= link_to "Printable Invoice (PDF)", products_path(#products, format:"pdf") %></p>
I know for certain that localhost:3000/products.pdf generates it just fine, but I'm having issues figuring out the correct path for the link.
#some instance variables
respond_to do |format|
format.html
format.xml {...}
format.json {...}
end
Does respond_to simply send all instance variables to the next webpage or it does something more?
I'm wondering how much data would be sent by respond_to. For example, if I have many instance variables #one #two #three etc. Are they all sent by respond_to? Any other data would be bundled and sent as well? ?
You instance variables will not be sent anywhere without your direction.
You probably have a .html.erb template that renders the instance variables when an HTML request is received (format.html).
For the xml and json responses, you need to tell Rails what to do. For instance, you could supply a template .xml.builder.
Rails can also render certain structures (arrays etc.) for you automatically, simply by calling render json: #one
Rails goes through the registered formats and tries to find a compatible format, otherwise, it will raise an error.
Example:
def index
#stories = Story.all
end
index action does not have a respond_to block. If a client asks to get the page in TEXT format, it will lead to the following exception:
ActionView::MissingTemplate (Missing template blogs/index ... with { ... :formats=>[:text], ...})
We can easily fix this by adding a respond_to block:
def index
#stories = Story.all
respond_to do |format|
format.html
format.js
end
end
After the change, the client will get 406 error when the format is not supported. Also, your index action will respond to two new formats: js and HTML.
This article explains all the ways you can use respond_to blocks.
I have a controller and all of the actions are not render by IE8, in Firefox and Chromer works ok. The problem is only with this controller, i have another that work ok.
The code is:
class CustomersController < ApplicationController
auto_complete_for :customers, :name
def search
unless params[:q].nil?
#customers = Customer.find(:all, :conditions => ['name LIKE ?',
"%#{params[:q]}%"])
end
respond_to do |format|
format.xml { render :xml => #customers}
format.json { render :json => #customers}
end
end
def index
#customers = Customer.find_index
end
def show
#customer = Customer.find(params[:id])
end
For example the index action is not getting render and instead IE8 display a download dialog, but if i edit the index action like this:
def index
#customers = Customer.find_index // a find all but ordered.
respond_to do |format|
format.html
end
end
Any ideas what is happening?
UPDATE:
For all of you interested, the problem was the templates files names.
All the files with a name like "invoice.erb" was sent back to the browser as content "text/erb" while the files like "customers.html.erb" was sent back as "text/html".
Once i renamed all the file to "html.erb" everything works ok
ie8 doesn't know what to do with xml or json but does know what to do with html. If you really want the browser to display the xml you could add :content_type => 'text/plain' to the block so it knows how to respond to it.
This is probably more a design or usage question but the main issue is using the Prawn plugin with Rails 2.3.4 and accessing the resulting PDF object to render it to a file.
The scenario is basically;
a controller with the respond_to block setup
a view with code for rendering the text, graphics etc to PDF
It looks like:
From Customer Controller
def show
#customer = Customer.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #customer }
format.pdf { render :layout => false }
end
From Customer View
pdf.text "Hello World"
pdf.text "Customer is #{#customer.name}"
This works fine, producing a PDF file in response to /customers/1.pdf, as expected with a PDF file being generated.
One of the other requirements is to render the pdf to a file and store a copy on the server. Prawn provides the method:
pdf.render_file {path_tofile}
So now if I include this in the View code I can of course save the file on the server. But I'd like to manage this in the controller, as it's related to logic, not view per se.
The first attempt was :
def show
#customer = Customer.find(params[:id])
#pdf = Prawn::Document.new()
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #customer }
format.pdf { render :layout => false }
pdf.render_file {path_to_file}
end
From Customer View
pdf.text "Hello World"
pdf.text "Customer is #{#customer.name}"
PROBLEM
The problem with this attempt is that the PDF is not rendered. I suspected the Controller instance variable is clashing with the Prawnto Plugin pdf variable. But even changing the PDF variable didn't work.
Any suggestions ?
This is how I use prawn in my rails app: http://yob.id.au/2009/05/30/prawn-and-x-accel-redirect.html - it doesn't use prawnto at all.
You can ignore the X-Accel-Redirect stuff unless you use nginx.
Alternatively, another one of the prawn core devs has put together this guide: http://wiki.github.com/sandal/prawn/using-prawn-in-rails