Why Rails fails to detect AJAX request in production?
Asked Answered
M

1

7

I am using rails 5.2.4.1, and I am wondering why I get this error when I try to access the API endpoint:

ActionView::MissingTemplate (Missing template api/schools/classrooms, application/classrooms with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :haml]}.

here is my action:

def classrooms
    render json: {classrooms: user.daip.class_rooms.as_json(:include => [:users]), max_classrooms: user.daip.classrooms} , content_type: 'application/json'
  end

I tried also to add default json response to all classrooms_controller as:

resources :schools, :defaults => { :format => 'json' }

I tried to add .json to the route but also, did not work

how can I debug this? as it works locally, but not at the production server? I am using nginx with passenger.

What could be the issue?

EDIT

I also tried:

ActiveModel::Serializer.config.adapter = ActiveModel::Serializer::Adapter::JsonApi

EDIT2 I found that header HTTP_ACCEPT is passed as:

"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"

I set it to application/json, text/plain, */* , still, rails search for a template!!

EDIT3

I tried to set default request to json as:

request.format = :json

and I tried to use format.json as:

def classrooms
    request.format = :json
    format.json {
    render plain: {classrooms: user.daip.class_rooms.as_json(:include => [:users]), max_classrooms: user.daip.classrooms}.to_json , content_type: 'application/json'
    }
  end

And I still have the same error, searching for a template..

EDIT4

Here is my request headers:

Host: myapp.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: application/json, text/plain, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/json
Referer: https://myapp.com/en/api/school-admin
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
TE: Trailers
Origin: https://myapp.com
Content-Length: 0

and route:

namespace :api, defaults: {format: :json} do
    get 'classrooms' => 'schools#classrooms'
  end
Mainmast answered 29/1, 2020 at 7:10 Comment(12)
You probably are not returning anything from your API method. By default, the rails returns the last value it calculated and looks for a template with same name as the action in views and renders it. In case, you want to override that behavior, you have to do something like this: render json: { results: your_output }, code: :ok in the last line. I don't know more than that about rails APIs. I hope it can solve your issue.Navvy
I see that you tried that. It probably has something to do with difference in configurations of your production and development but I don't have enough knowledge about that. Apologies.Navvy
Thanks, if I find how to let rails respond with json for all actions in the controller, thus avoid search for any template, that would solve the issue I think..Mainmast
It may help you: https://mcmap.net/q/1626688/-rails-return-json-instead-of-html/10313894Navvy
or this: https://mcmap.net/q/460890/-rails-4-how-to-render-json-regardless-of-requested-format/10313894Navvy
you can try this too: render plain: { hash_content }.to_json, content_type: 'application/json'. reference: github.com/rails/rails/issues/23923Navvy
I tried plain: but did not work eitherMainmast
What about adding application/json to the content type of your ajax request?Sportscast
can u post yr ajaxing lines, and yr routes dnt have classrooms method, or am i missing smth here, nor you have not posted itScut
kindly see edit4 aboveMainmast
Implicit rendering should only kick in if you don't call render. Can this really be something simple like the same code not running on production? Look at the rest of the log. Is the expected controller being called?Centripetal
I've checked the production log, the expected controller is being calledMainmast
M
3

After burning long previous hours of frustration, I decided to debug the code it self that I was trying to create json object of. I passed an empty json object, and then, I got status 200 response with empty json object! So, the error ActionView::MissingTemplate was completely misleading!!, made me blind of the real error. I ran the code user.daip.class_rooms.as_json(:include => [:users]) in rails console, and I got this error:

Cannot have a has_many :through association 'ClassRoom#users' which goes through 'ClassRoom#class_rooms_users' before the through association is defined

Checked class_room model, and oh! I just had to flip those lines:

  has_many :users, through: :class_rooms_users
  has_many :class_rooms_users

to:

  has_many :class_rooms_users 
  has_many :users, through: :class_rooms_users

That was really sad story, the motto is, never trust error message when every thing seems to be fine, sad developers.

Mainmast answered 1/2, 2020 at 11:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.