Search code examples
ruby-on-railsajaxcoffeescriptpartial-viewscontent-type

Rails 4 - MissingTemplate/Missing Partial Error, Only in Production


We just secured our application with an SSL certificate. Moving to HTTPS is proved more complex than we thought and we're currently sorting through a few of the resulting bugs.

We have an AJAX call in CoffeeScript, where rails responds by rendering the html of a partial. This is working perfectly in development.

CoffeeScript:

coffee_method: (pos, uid) =>

  $.ajax '/contoller/test/',
    type: 'POST'
    data:
      pos: pos
      uid: uid
    success: (data) ->
      $('#result-div').html(data) #Populates side menu with _next_destination_menu content
    error: ->
      alert 'How embarassing! Something went wrong - please try your search again. '

Controller:

def test
  ... #do some stuff

  puts "format requested: #{request.format}"
  puts "format url_encodeded: #{request.format.url_encoded_form?}"

  render partial: 'trips/_test' #app/views/trips/_test.html.erb

end

However, in production, we get the following error: ActionView::MissingTemplate (Missing partial trips/_test with {:locale=>[:en], :formats=>[:url_encoded_form], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}.

After some digging, I figured out the request in production was a different format. Using those puts lines in the controller to debug, here are the results:

Production:

format requested: application/x-www-form-urlencoded
format url_encodeded: true

Development:

format requested: */*
format url_encodeded: false

What is the best way to handle this issue. Do I:

  • Change the content type of every AJAX call in the CoffeeScript?
  • Add a respond_to...format.url_encoded_form {render partial: trips/test} to the controller?

The latter seems like I would be duplicating code, because I want to render the same partial, regardless of the format the request comes in. I tried format.all {...} but encountered the same issue. Any best practices are appreciated!

Update:

Specifying the response type directly gives me the same missing template error:

respond_to do |format|
  format.html  {render partial: 'trips/test'}
  format.json  {render partial: 'trips/test' }
  format.url_encoded_form {render partial: 'trips/test'}
end

Update 2:

The Request headers for both localhost and production are the same, the content type is application/x-www-form-urlencoded, even though format.url_encoded_form? returns false.

Accept:*/*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4
Connection:keep-alive
Content-Length:37
Content-Type:application/x-www-form-urlencoded; charset=UTF-8

Solution

  • You could try passing in the format, locale, and handlers exactly as requested:

    render(
         partial: 'trips/test',
         formats: [:html, :js, :json, :url_encoded_form],
         locale: [:en],
         handlers: [:erb, :builder, :raw, :ruby, :coffee, :jbuilder])