render_to_string in an after filter

I'm using render_to_string in an after_filter, which renders a partial
that is sent to a web service. Here's the code:

class MyController < ApplicationController

after_filter :post_to_webservice

def show
# show logic
end

def post_to_webservice
stuff = render_to_string :partial => 'stuff'
webservice_post(stuff)
end

I get a DoubleRenderError in the after filter. As I understand it,
the 'show' action will be rendered, but won't be sent to the browser
until the after filter is called. Because the 'show' action is
already rendered (but not sent), we get a DoubleRenderError when
render_to_string is called. Ideally, render_to_string should be
atomic and not mess with current rendering.

The work-around is to just call render_to_string before rendering
'show', but I want to keep my controller code DRY by putting the
webservice logic in an after_filter.

So is this a bug or a feature?

Thanks,
Shane

I've run into the same issues with render_to_string and there was some
discussion and I think it basically boiled down to it being a bug. I
don't think it should mess with the current rendering either, but I'm
not sure if this has been looked at for 2.0.

I took a look into it before, but didn't get around to developing a "fix".

I've run into the same issues with render_to_string and there was some
discussion and I think it basically boiled down to it being a bug. I
don't think it should mess with the current rendering either, but I'm
not sure if this has been looked at for 2.0.

If you have a test case which exposes this, we can take a look.
There have been some changes to how render_to_string works, so
hopefully we've fixed this for you, but the best way to know for sure
is to write a test case for us :slight_smile:

This caught my attention (since I was having a play with merb's way of
handling rendering) so I decided to see if I can replicate it with a
test case.

Mostly the reason why it's doing that, Shane, is because
render_to_string doesn't work quite well if called _after_ the action
has been rendered.

I've opened a ticket with a failing test that demonstrates the problem
here: http://dev.rubyonrails.org/ticket/10334 (and replicating most of
the ticket details here for discussion)

If executed in an after_filter, the call to render raises a
DoubleRenderError as it has already performed a render earlier (in the
action).

It's not enough to just make render think that it hasn't already
rendered (which can be achieved by temporarily making the performed?
check return false) since the render_to_string call would most likely
modify the response (such as the assigned variables and even the
response.body).

So even though I'm not one to speak with authority on this area of
Rails, I'd like to suggest there could be some merit in attaching some
kind of action/view context to each render (similar to how merb does
it).

But first I'd appreciate hearing everyone's opinions on this since it
seems like a significant refactoring for what seems like an edge
case.

Cheers,
Chu Yeow

But first I'd appreciate hearing everyone's opinions on this since it
seems like a significant refactoring for what seems like an edge
case.

We're hoping to spend some time tidying up the render implementations
for 2.1, perhaps we can just take note of this as something to bear
in mind.

Well merb needs a context for each render because multiple renders can
potentially be running in different threads. This might be overkill
for Rails though. Thanks for the failing test case. I'll take a
look.

Shane