What does respond_to do? - ruby-on-rails

#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.

Related

Rails: Is it neccessary to wrap my POST response in a respond_to block?

I have an AJAX form that sends a POST request to the controller. The controller responds in JSON.
Here, reponse is JSON:
def send_form_response(response)
render json: response
end
The above works fine but I keep seeing examples that use respond_to. My form still works when I wrap my response in the respond_to block.
def send_form_response(response)
respond_to do |format|
format.json { render json: response }
end
end
Does using respond_to give me any benefits? Will anything bad happen if I don't? Or does it make no difference in this case?
respond_to is used to handle multiple responses in the controller#action
If the client wants HTML in response to this action, just respond as
we would have before, but if the client wants XML, return them the
list of people in XML format." (Rails determines the desired response
format from the HTTP Accept header submitted by the client.)
Say for example, If you want send_form_response(response) to respond with HTML and JSON, then you would do it like this
def send_form_response(response)
respond_to do |format|
format.html
format.json { render json: response }
end
end
You can do the same with respond_with
respond_to :html, :xml, :json
def send_form_response(response)
respond_with response
end
So, to answer your questions
Does using respond_to give me any benefits?
Not in your case, where you are requesting only one response
Will anything bad happen if I don't?
Not in your case, no.
Does it make no difference in this case?
No, not at all.

Rails Controller - What is the purpose of "respond to do format" html and json?

Ruby on Rails Question:
Inside the controller you have seven REST actions. Almost all of them have respond to do format xml/html or json. I have no idea what this means. Can you please explain it's purpose.
For example:
def index
#tweets = Tweet.all
respond_to do |format|
format.html
format.json { render json: #tweets }
end
end
What is the purpose of the "respond to" part that contains the html and json? What do these formats do?
Also, what is the difference between xml and html? Sometimes I see xml and other times html.
Thank you
Its just a way of telling your controller how to respond to different request types. For example your client could want html or xml information from you:
def index
#people = Person.find(:all)
respond_to do |format|
format.html
format.xml { render :xml => #people.to_xml }
end
end
What that says is, "if the client wants HTML in response to this action, just respond as we would have before, but if the client wants XML, return them the list of people in XML format." (Rails determines the desired response format from the HTTP Accept header submitted by the client.)
http://apidock.com/rails/ActionController/MimeResponds/InstanceMethods/respond_to

Rails respond_to redirect all requests except X mime-type

Below is the typical respond_to block im using in my controller
respond_to do |format|
format.html # show.html.erb
end
I want to restrict all mime-types except html(lets say).
Couldn't come up with a solution, how is this possible? This block does nothing if the request is json, this is OK but what I want is to redirect any requests that are not html.
Thanks
The format object yielded by respond_to has all of the usual mime types (html, js, xml, etc), and it also has a catch-all mime type any that will handle everything else. So, in this case:
respond_to do |format|
format.html
format.any { redirect_to :foo }
end
will use default rendering for html, and will redirect for everything else. See the docs for (a tiny bit) more information: http://apidock.com/rails/ActionController/MimeResponds/respond_to

rails fresh_when/stale? usage

In my post_index action, I generate different kinds of "#posts" like..
def index
case params[:listing_type]
when "all"
#posts = get_all_post_from_memcached
when "most_popular"
#posts = get_all_most_popular_from_memcached
respond_to do |format|
format.html
format.js #for ajax reqeusts
format.xml #for rss etc
end
end
end
##updated
def index
case params[:listing_type]
when "all"
#the key here is teh same key I used for memcached
if stale?(:etag => 'all_posts_key')
#posts = get_all_post_from_memcached
else
head :not_modified and return
end
when "most_popular"
if stale?(:etag => 'most_popular_key')
#posts = get_all_most_popular_from_memcached
else
head :notified and return
end
respond_to do |format|
format.html
format.js #for ajax reqeusts
format.xml #for rss etc
end
end
end
From what I understand fresh_when takes a etag, and it is to be used if there is no difference in different kinds of rendered (in my case the rendering is different based on html or ajax)
and
stale? also takes an etag and surrounds the respond_to block.
In this case the etag will be different based on the different listing types. But it seems there isn't much flexibility in the way fresh_when or stale? can be used here?
Thanks
update. I changed the original block a little and now get a double render error what am I doing wrong, should "head :notified and return" just return the header and not touch the respond_to block?
If you have special response processing like the one in show method, then use stale? helper. If you don’t have any special response processing like the one in edit method and using default-rendering mechanism (i.e., you’re not using respond_to or calling render yourself) then use fresh_when.

Understanding Ruby Syntax [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
What is the best way to learn Ruby?
Explain Iterator Syntax on Ruby on Rails
I'm still learning ruby, ruby on rails and such. I'm getting better at understanding all the ruby and rails syntax but this one has me a little stumped.
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #contact_lists }
end
respond_to is a method that takes a proceedure, I think. The two formats look like they may be method calls too, but I don't know.
respond_to is a method which takes block. The block takes one argument, which here is called format.
Now you call two methods on format. html which you call without arguments. And xml which you call with a block.
This block takes no arguments and contains a call to the render method with a hash as an argument. The hash contains the key :xml and the value #contact_lists.
Yeap, you're right.
Ruby method calls are a bit puzzling at first, because you can ommit the parethesis, and they may receive code blocks.
So, this is the explaination:
respond_to do |format|
Invoke the method respond_to and pass it a block on what to do with the format it will receive.
format.html # index.html.erb
With that object called format invoke the method html
format.xml { render :xml => #contact_lists }
And the method xml which in turns receive another block ( do / en and { } , are different syntax to pass block. )
end
Finish the first block
See this other , other answers.
I think this post can help you.
Also, take a minute to read the respond_to documentation.
It is worth to know that this method has changed in Rails 3.
Without web-service support, an action
which collects the data for displaying
a list of people might look something
like this:
def index
#people = Person.find(:all)
end
Here’s the same action, with
web-service support baked in:
def index
#people = Person.find(:all)
respond_to do |format|
format.html
format.xml { render :xml => #people.to_xml }
end
end
What that says is, "if the client
wants HTML in response to this action,
just respond as we would have before,
but if the client wants XML, return
them the list of people in XML
format." (Rails determines the desired
response format from the HTTP Accept
header submitted by the client.)
Supposing you have an action that adds
a new person, optionally creating
their company (by name) if it does not
already exist, without web-services,
it might look like this:
def create
#company = Company.find_or_create_by_name(params[:company][:name])
#person = #company.people.create(params[:person])
redirect_to(person_list_url)
end
Here’s the same action, with
web-service support baked in:
def create
company = params[:person].delete(:company)
#company = Company.find_or_create_by_name(company[:name])
#person = #company.people.create(params[:person])
respond_to do |format|
format.html { redirect_to(person_list_url) }
format.js
format.xml { render :xml => #person.to_xml(:include => #company) }
end
end

Resources