Stupid WTF! ActionView::MissingTemplate Exception: Missing template users/_user.erb

by Justin Ball on June 5th, 2009

If you've spent much time working with Ruby on Rails and more especially if you've done anything with json you might have run across errors like this:

ActionView::MissingTemplate Exception: Missing template users/_user.erb

I was having this problem and doing a lot of cursing which is common when I stay up and write code until 2am which I know I should do and I also know that I shouldn't write really long run on sentences but I do it anyway.

This error is usually the result of some code that looks like this:

 
format.json do
  @user_html = render_to_string( :partial => 'users/user', <img src='http://www.justinball.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> bject => @user )
  render :json => { :success => true,
                              :user_html => @user_html  }
end
 

The cause of this error is that the format of the current request is :json. There isn't an _user.json.erb template so Rails tries to find an _user.erb file. That doesn't exist either and boom you spend the night sounding like a sailor.

Now I don't pretend to be an expert but I have been accused of being a hack. I solve the problem by changing the template format:

 
format.json do
  @template.template_format = :html
  @user_html = render_to_string( :partial => 'users/user', <img src='http://www.justinball.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> bject => @user )
  render :json => { :success => true,
                              :user_html => @user_html  }
end
 

The key is the addition of:

 
  @template.template_format = :html
 

Don't yell at me if it breaks. I'm open to better suggestions but for now this does work and now my I can find other reasons to stay up late.

  • jbasdf
    I think the question of whether to render and entire partial or a few objects depends on the situation. A lot of times it feels more dry to use the partials so that you don't have to reconstruct the html on the client. On the simple end you could ignore json and just do things like jQuery('#thing-to-replace').replaceWith(<%= escape_javascript(render('shared/test')) %>); If you want to be more open you could use json and just send down snippets of html (from the partials) embedded in the result. That way others could use your data. You could also just send the data (no partials rendered) as json and then on the client parse that and perform whatever actions you need.
  • shripad
    This works though:

    My view: /app/views/shared/_test.html.erb
    <div><%= test %></div>

    My actions respond_to block:

    @reply = render_to_string(:partial => '/shared/test', :locals => {:test => @test})
    format.js { render :json => @reply }

    Btw. This solution saved me from building the UI all over again! Seems more DRY. However don't you think the JSON transport will become bulky? What if the partial you have got to render is huge? I would rather send few objects than an entire partial. What is your thoughts on this?
  • Patelakash_a
    Thanks.......you saved me from getting frustrated!!!

    Thanks for sharing!!!!
  • thanks for that article. I had exactly the same issue with partials inside partials....your hack solved it.
  • You can also add the extensions of the partial to force it to render the html one:

    render_to_string(:partial => 'users/user.html.erb')
  • Louis
    @MicahWedemeyer: explicitly stating the extensions in this line won't solve your problem if your partial contains more partials. E.g. if user.html.erb tries to render a partial called "contact_info", Rails won't automatically look for .html.erb for that template.
blog comments powered by Disqus