Need help : How to render HTML inside of a JSON request

We have an app that is in production with Rails 2.1.2 and I'm about to upgrade to 2.3.2. However, I am having a problem with a number of AJAX calls and I could really use some help. The client will make an AJAX call to receive a json response, and the response includes an html string as one member of the json data object.

We render the html to a string (render_to_string). and return the object. However, in the 2.3.2 version, we are receiving an erorr that some of the partials called inside of the render can't be found. I've isolated it to the partials that aren't fully qualified names. For example, this appears to fail:

render :partial => 'comments/partial_name'

If I change it to :

render :partial => 'comments/partial_name.html.erb'

and it works. It appears as though the fact that the call is a JSON request from the client is causing the render engine not to search for .html and .html.erb in the path, thus they fail.

Any ideas?

Russell

RFine wrote:

render :partial => 'comments/partial_name'

If I change it to :

render :partial => 'comments/partial_name.html.erb'

and it works. It appears as though the fact that the call is a JSON request from the client is causing the render engine not to search for .html and .html.erb in the path, thus they fail.

You got it. Why are you returning .html from a ajax/json request from the client, anyway? Generally, ajax requests from the client get back javascript (or specifically json), not html!

Rails is trying to help you with this general case, because you can have the same action that will return partial.html.erb if it's an html request, or partial.js.erb if it's an AJAX request. I forget exactly how Rails determines when the format is js, but I know if you're using any of the Rails helper methods for ajax callbacks, they definitely include a query param to tell Rails what's what.

So you can change the render call like you say. Or you COULD rename the partial in the old way partial_name.erb, so Rails will use it for any format request. But that's kind of weird (and now i'm not entirely sure it'll work). Or you could reconsider why you want to return HTML (rather than js/json) to a js request in the first place. Or you could take a look at respond_to to see how you can return different views for different request types. http://api.rubyonrails.org/classes/ActionController/MimeResponds/InstanceMethods.html#M000368

Thanks, Jonathan. First off, I inherited this code base and I realize that there is a better solution... specifically to do a request with update. The request ask for json because they return both data elements which are used in the page and an html block as a replacement for a section. If there were only one call... I would just fix it by hand, but this approach has been used in multiple places in the code base. They make a call that constructs a json object, and one element in it is a string of html to replace a div. Unfortunately, when we call render_string -- now the render wont look for .html.erb objects. I've tried adding :content_type=:html to the render call, to no avail. I've also tried adding Mime::HTML and 'text/html' as :content_type parameters.

I think I just need to temporarily override the request content type during rendering, but I can't figure out how.

Russell