Versions
Ruby: 2.4.1
Rails: 5.2.3
jQuery: 3.4.1
Problem
A request is sent from a page through Ajax which has json
as a format but a Rails server thinks this request has a format text/html
.
As a result, it generates ActionView::MissingTemplate
.
ActionView::MissingTemplate (Missing template likes/json, application/json with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :arb, :slim, :coffee, :jbuilder]}
My code
routes.rb
Rails.application.routes.draw do
resources :likes, only: %i(create destroy)
controller
class LikesController < ApplicationController
def create
item = Item.find(like_params[:item_id])
like = Like.new(user: current_user, item: item)
if like.save
count = Like.where(item: item).count
render :json, { count: count, like_id: like.id }
else
render :json, {}
end
end
view(slim)
.like-btn
a href='#'
.count = @like_count
javascript:
$('.like-btn a').click( e => {
e.preventDefault()
$.ajax({
url: '#{likes_path(item_id: @item.id)}',
dataType: 'json',
method: 'POST',
success: (data) => {
$('.like-btn .count').text(data.count)
}
})
})
What I did
- ruby
- try
respond_to
- try
render :plain, some_json, content_type: 'application/json
- try
- javascript
- try
$.post
- set
contentType
,type
,data
- try
request object
# inside LikesController#create
(byebug) request.headers.to_h["CONTENT_TYPE"]
"application/x-www-form-urlencoded"
(byebug) request.format.to_s
"text/html"
Update
I tried #{likes_path(item_id: @item.id)}.json
and 'likes?item_id=#{@item.id}
but they didn't work and generated the same error.
Here is the request object. It doesn't have json
in the url and the format is recognized as text/html
even though the url in javascript has json
.
# inside LikesController#create
byebug) request.url
"http://localhost:3001/likes?item_id=4"
(byebug) request.format
#<Mime::Type:0x007feea72326a0 @synonyms=["application/xhtml+xml"], @symbol=:html, @string="text/html", @hash=-2254575977737173308>
Update2
I tried #{likes_path(item_id: @item.id, format: :json)
which generated likes.json/item_id=4
, but the same error was generated.
# inside LikesController#create
(byebug) request.url
"http://localhost:3001/likes?item_id=6210"
(byebug) request.format.to_s
"text/html"
Update3
I had an error in the success
attribute in $.ajax
and after removing that error, the Rails server started to recognizing the format as application/json
but an error was still generated.
ActionView::MissingTemplate (Missing template likes/json, application/json with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :arb, :slim, :coffee, :jbuilder]}.