First, 2 common (basic) approaches:
# returning from some FoosController method
respond_to do |format|
# 1. render the javascript directly
format.js { render :json => @foo.to_json }
# 2. render the default template, say update.js.erb
format.js { render }
end
# in update.js.erb
$('#foo').html("<%= escape_javascript(render(@foo)) %>")
These are obviously simple cases but I wanted to illustrate what I'm talking about. I believe that these are also the cases expected by the default responder in rails 3 (either the action-named default template or calling to_#{format} on the resource.)
The Issues
With 1, you have total flexibility on the view side with no worries about the template, but you have to manipulate the DOM directly via javascript. You lose access to helpers, partials, etc.
With 2, you have partials and helpers at your disposal, but you're tied to the one template (by default at least). All your views that make JS calls to FoosController use the same template, which isn't exactly flexible.
Three Other Approaches (none really satisfactory)
1.) Escape partials/helpers I need into javascript beforehand, then inserting them into the page after, using string replacement to tailor them to the results returned (subbing in name, id, etc).
2.) Put view logic in the templates. For example, looking for a particular DOM element and doing one thing if it exists, another if it does not.
3.) Put logic in the controller to render different templates. For example, in a polymorphic belongs to where update might be called for either comments/foo or posts/foo, rendering commnts/foos/update.js.erb versus posts/foos/update.js.erb.
I've used all of these (and probably others I'm not thinking of). Often in the same app, which leads to confusing code. Are there best practices for this sort of thing? It seems like a common enough use-case that you'd want to call controllers via Ajax actions from different views and expect different things to happen (without having to do tedious things like escaping and string-replacing partials and helpers client side).
Any thoughts?