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