Typical usage is:
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #users }
end
And now I want to also pass a string named "teststring".
I've seen reference to using
:local => {:users => #users, :another => #another}
But I don't know how to merge the two together. I just haven't seen everything all together. Not much documentation to really explain the :xml in that line. And I don't know if I can deal with the string with :teststring => teststring?
And lastly, how do I deal with them in my index.html.erb now that I have multiple variables? Do they get passed with the same name from the render command?
Thanks.
If you want to render custom XML, you'll need to create a index.xml.erb file in the corresponding view directory for the controller. It works just like any HTML template you'd use, then:
app/controllers/home_controller.rb:
def index
#users = ...
#another = "Hello world!"
# this `respond_to` block isn't necessary in this case -
# Rails will detect the index.xml.erb file and render it
# automatically for requests for XML
respond_to do |format|
format.html # index.html.erb
format.xml # index.xml.erb
end
end
app/views/home/index.xml.erb:
<?xml version="1.0" encoding="UTF-8"?>
<document>
<%= #users.to_xml # serialize the #users variable %>
<extra_string><%= #another %></extra_string>
</document>
(You can read about ActiveRecord's to_xml method here.)
Related
Here is a Rails code:
respond_to do |format|
format.html
format.xml { render :xml => #users }
format.json { render :json => #users }
end
I know what it does. But I don't know the meaning of the commands syntax-wise.
format.xml -- what is xml, is this a method which an object format has, correct? Where do I find its signature (or description)?
{ } -- a block or a hash? I think this is a block.
render -- a method? where do I find its signature (where in api docs)?
:xml => #users -- a hash, where :xml => is a key, correct?
So it could be reprented as, right?:
respond_to do |format|
format.html
format.xml do
render(:xml => #users)
end
format.json do
render(:json => #users)
end
end
format.*
Using the debugger, I learnt that format is an instance of ActionController::MimeResponds::Collector. It includes AbstractController::Collector, which uses method_missing to respond to various format calls.
if Mime::SET.include?(mime_constant)
AbstractController::Collector.generate_method_for_mime(mime_constant)
send(symbol, &block)
else
# ...
{ render xml: ... }
Looking at method_missing, it's clear that it expects a block.
render
Yes, render is a method. Documentation.
:xml => #user
Yes, it's a hash. The key is the symbol :xml. It can also be written as
render xml: #user
render(xml: #user)
render({xml: #user})
render({:xml => #user})
format comes from the request made to the method, http://app.com/controller/method.format where format could be .html or .csv etc. The meaning of format.xml is simply to check if the user requested an xml page (http://app.com/controller/method.xml.
Block, just like you describe.
At the apidock! http://apidock.com/rails/ActionController/Base/render
Correct, render will act depending on the key that exists. In your case, as the existing key is :xml the render method will output #users formatted as XML.
This is how I generate XML for purchase model:
# GET /purchases/1
def show
#purchase = Purchase.find(params[:id])
#purchases = Purchase.all
respond_to do |format|
format.html # show.html.erb
format.xml { render :action => "something.xml.builder", :layout => false }
end
end
Now I'd like to get this rendered XML as string into variable so I could post it to WebService.
How can I get XML through sales_invoice.xml.builder without rendering it?
I don't want use dirty hacks and loading XML from http://appurl/purchases/1.xml
Thanks!
What I was looking for was render_to_string method.
A rails newbie here
I have 2 actions in my controller 1) index 2) refine_existing.
Both of them show the results in the same format.
How do I reuse the index.html.erb file?
When I try the following, it complains about refine_existing.erb not being present.
def refine_existing
...
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #results }
end
end
my index action looks like this
def index
#some logic to get #results
#set some session variables etc.
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #results }
end
end
Do I have to refactor my index view to contain partials that
a) make the headers
b) render #results
and reuse them?
Even though, both index.html.erb and refine_existing.html.erb will look exactly the same
Is there any way I can say in my refine_existing action to use index.erb view?
thanks in advance
By convention, if you don't specify a template name Rails looks for one matching the action. You can override this by calling render explicitly with the desired template name. The only wrinkle is that the path is relative to TEMPLATE_ROOT, which is normally app/views:
def refine_existing
...
respond_to do |format|
format.html { render :template => "<table_name>/index.html.erb" }
end
end
replacing table_name with the "tablized" form of the model. E.g. if your controller is PostsController, then posts. So your template would then live in app/views/posts/index.html.erb -- if you've customized paths somehow adjust as necessary.
I am experimenting with Rails and was wondering what's needed to allow/add support for JSON requests?
I have a vanilla installation of Rails 2.3.5 and the default scaffolding seem to provide support for HTML & XML requests but not JSON.
class EventsController < ApplicationController
# GET /events
# GET /events.xml
def index
#events = Event.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #events }
end
end
# GET /events/1
# GET /events/1.xml
def show
#event = Event.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #event }
end
end
...
I'm new to this but it would appear as though i would need to add a format line in each method along the lines of:
format.js { render :js => #event.json }
couldn't this be done automatically? perhaps there's a template somewhere i need to update...or a flag i can set? Or perhaps, and most likely, I've missed the boat entirely?!?
You do:
format.json {render :json=>#event}
That will render the default activerecord JSON for the model
The option of ease of use is that you can write a private method which takes the format object and an object to render and then, based on the format, renders different things. Example:
class MyController<ApplicationController
def show
#event=Event.find(params[:id])
respond_to do {|format| myRenderer(format,#event)}
end
...
private
def myRenderer(fmt,obj)
fmt.json {render :json=>obj}
fmt.html
fmt.xml {render :xml=>obj}
end
I'm a newcomer to Rails, and have been following the tutorial on the rails webpage.
Using the scaffold instruction to create a "post" model, I found that the new action in the controller has a special directive for XML format:
def new
#post = Post.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #post }
end
end
I can't see the reasoning for supporting an XML request when creating a new post. Browsing to /posts/new.xml returns nothing. What is the purpose of this?
The reasoning for it behind the new action is simply to provide a xml client with the default data (or something else if you want).
The format directive is being used by all routes, and you don't need to support a format unless you want to.
The above code could might as well have looked like:
respond_to do |format|
format.html # renders new.html.erb
format.xml { render :xml => {:message => "XML is not supported"} }
format.json { render :text => #post.to_jsonĀ }
format.js # renders new.js.erb
end
Also, this is not limited to the new action, but is available in all your actions. The format to use is either taken from the url (if the route is set up to use it), or from the HTTP-Accept header that the browser sends.