I am trying to have a json response in which some value is html rendered by a partial
#projects_Controller.rb
def index
  respond_to do |f|
    f.json 
  end
end
# index.json.erb
  {
     "html":"<%= raw escape_javascript(render :partial => 'projects/disclaimer') %>"
  }
But I get the following error:
  ActionView::Template::Error (Missing partial projects/disclaimer with {:handlers=>[:erb, :rjs, :builder, :rhtml, :rxml], :formats=>
  [:json], :locale=>[:en, :en]} in view paths "c:/rails/app/views", "c:/rails/vendor/plugins/more/app/views", "C:/Ruby192/lib/ruby/gems/1.9.1/gems/devise-1.1.8/app/views")
It appears JSON requests renders partial with .json.erb in its name but not .html.erb, which is what I have. Is there a way for me to specify 'html'.
ADDED: If the request is 'js', and in index.js.erb I render the almost same code: # index.js.erb
  disclaimer = {
     "html":"<%= raw escape_javascript(render :partial => 'projects/disclaimer') %>"
  }
it does find the projects/disclaimer.html.erb and renders it correctly. I wonder why is there such an inconsistency in that if one requested js, any partial rendering in its template will look for partial_name.html.erb but if one requested json, the partial rendering would ask for partial_name.json.erb?
Thank you
Got it: All one needs is this line in the .json.erb file <% self.formats = ["html"] %>
So the full index.json.erb
      <% self.formats = ["html"] %>
      disclaimer = {
        "html":"<%= raw escape_javascript(render :partial => 'projects/disclaimer',
                    :content_type => 'text/html'), 
                    :locals => {:localVariable => @localVariable} 
                %>"
      }
                        My answer is similar to Nik's above. I have the following helper for json.erb templates:
# helpers useful for json.erb templates
module JsonHelper
  # Same as render but force actionview to look for html templates instead of json.
  def render_html(options={}, locals={}, &block)
    old_formats = formats
    self.formats = [:html] # hack so partials resolve with html not json format
    render options, locals, &block  
  ensure
    self.formats = old_formats 
  end 
  # json escape a string. For example <%=json "some { string }" %>
  def json(value)
    raw value.to_json
  end 
end
So now I can write templates like
{
  "html": <%=json render_html(:partial => 'some_partial') %>,
  "status": success
}
This would be nicer if actionview allowed rendering with a content_type like in 23tux's example (which doesn't work for me). It would also be nicer if only *.html.erb underwent html escaping instead of all *.erb files.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With