Tricky respond_to and layout problem

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 :slight_smile:

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 :wink: ).

Peace,
Phillip

Hi,

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 :slight_smile:

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}

format.xml { render :xml => @
foo.to_xml }

Hi Michael,

format.xml {render :layout => false}

format.xml { render :xml => @ foo.to_xml }

If I had a single object that could be rendered to xml, then, yes, this would have been the simplest and most correct approach. But as it turns out, there is some logic in my rxml view that does some calculations before it renders the xml. I'll do some checking to see if there is an easier way for me to accomplish what I need to.

Thanks for the comment.

Peace,
Phillip