Hi all…
I just spent the better part of an hour wrestling with a finicky
situation, and since there was some discussion earlier regarding
multiple layouts, I thought I’d share my experience in the hope it
might save someone a bit of hair-pulling
In one of my controllers, I had these actions:
def welcome
end
def welcome_xml
end
def math
end
def math_xml
end
The actions sans “_xml” are simple actions that render a view. The
only difference between them is the layout used: welcome uses a one
column layout while math uses a two column layout. The two actions
that do have “_xml” are for generating xml packets of some statistics
that are related to the non-xml actions. They are sort of like a web
service in that they will be consumed by external sources (flash
movies, etc). As it was, I didn’t want the xml actions rendered in a
layout, which is where my choose_layout method came from:
def choose_layout
if action_name == ‘welcome’
‘one_column’
elsif ![‘welcome_xml’, ‘math_xml’].include?(action_name)
‘two_column’
else
nil
end
end
Using that, I got the results I desired. Until the “let’s do things
the right way” bug bit me. I looked at the xml actions and thought,
“I should be using respond_to”, so I set about making the
modifications. I changed the non xml actions to be
def welcome/math
do something
respond_to do |format|
format.html
format.xml
end
end
and made sure that my view files were welcome.rhtml/rxml and
math.rhtml/rxml. The stage was set for rails goodness to “Just
Work”…but it didn’t. When I hit /controller/math.xml, I got an
error about malformed xml. As it turned out, the xml was being
rendered in a layout. Since the action names were no longer
‘welcome_xml’ and ‘math_xml’, the choose layout method wasn’t working
as it once did. So I tried this:
format.xml {render :layout => false}
thinking that the xml view would be rendered without a layout. Well,
it was, almost. A layout was not used, but for some reason that I
could not determine, the rhtml view was rendered instead of the rxml
view, even though my url was /controller/math.xml.
Much googling didn’t really turn up a silver bullet, but enough
little pricks in the brain were generated to get some ideas
formulating. I did some experimenting with action_name and concluded
that even though I used math.xml, the action name was still math.
The only way to tell the difference between the requests was to know
what the format is. On a whim, I inspected params[:format] when I
hit /controller/math.xml. And there it was, as big as life, “xml”.
Woohoo! I ended up changing my choose_layout method to consider params
[:format], like so:
def choose_layout
if params[:format] == ‘xml’
nil
elsif action_name == ‘welcome’
‘one_column’
else
‘two_column’
end
end
and taking the {render :layout => false} off of the format.xml line.
So now it all works the way I expect, and want, it to.
Hopefully this will help someone (and maybe make up for my silly
mistakes earlier today ).
Peace,
Phillip