As a new comer for ruby, I feel confused for this snippet:
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @posts }
end
I understand that if format is .html, it will give html response and if
format is .xml, it will give out xml response.
So this block "do |format| ... end" is case switch like in C++. I have
difficulty to understand though in ruby, if the user passing .html, as a
sequential execution (notice in ruby this is not a case switch
statement), what prevent ruby from executing "format.xml { render :xml
=> @posts }" line?
To my feeling (though I know I am wrong for sure), these two lines will
always be executed no matter what kind of format is passed in:
So this block “do |format| … end” is case switch like in C++. I have
difficulty to understand though in ruby, if the user passing .html, as a
sequential execution (notice in ruby this is not a case switch
statement), what prevent ruby from executing "format.xml { render :xml
=> @posts }" line?
Not really - the block is a ruby block. At some point (or multiple times) the respond_to method will call yield and then execution will transfer to the inside of the block. A method doesn’t have to execute its block at all, and it can also choose to keep it as a Proc object to use later.
To my feeling (though I know I am wrong for sure), these two lines will
always be executed no matter what kind of format is passed in:
These 2 lines will both be executed (at least in some sense). When .html is called rails doesn’t render an html response immediately - it merely records that an html response would be acceptable. Similarly when you call .xml it records that xml is an acceptable format, and saves the block passed. So when you get to the end of that block rails knows that html and xml are acceptable formats (in that order) and how it should behave for each one.
Then rails goes over all the acceptable formats looking for one that matches the current request. Only when it finds one that matches will it execute the correspond block (render :xml …) or the corresponding default action (for the html one)
I’ve simplified slightly, but that is the general gist of what is happening (if you are curious action_controller/metal/mime_responds is where this is implemented)