Reputation: 697
I have a search page in my app, where there is an ajax search form. The search form works properly, passing parameters to the model to filter the search, and the model returning a collection of results. Upon search submit, @results are rendered on the page. Each @result then has a link to an action on it, like:
<%=link_to "Message", message_user_path(:id => user.id), :remote => true%>
Where this action in the controller is:
respond_to :js, :html
def message
@user_id = params[:id]
@user = User.find_by_id(@user_id)
respond_to do |format|
format.html
format.js
end
end
and this responds with message.js.erb, which triggers a messaging panel to pop up with a message to the user. All of this is working correctly, checking the log I see the correct get request sent, and the correct format being processed:
Started GET "/users/3/message"
Processing by UsersController#message as JS
However, if I refresh the page and try to click the same link that was working before, I get the error Template is Missing. Checking the log, I see that now there are two requests sent, first an html then the same js request.
Started GET "/users/4/message"
Processing by StudentsController#message as HTML
...
Completed 406 Not Acceptable in 3ms (ActiveRecord: 1.0ms)
Started GET "/users/4/message"
Processing by StudentsController#message as JS
The html request throws the missing template error. Does anyone know why refreshing the page causes rails to attempt to respond with an html request to a remote link?
EDIT: routes.rb
resources :students do
member do
get 'message'
end
end
Upvotes: 15
Views: 17477
Reputation: 1
My form with remote: true
was inside another form and I didn't know it.
So make sure it isn't inside another form.
Upvotes: 0
Reputation: 789
For newer versions of Rails, this should be fixed where using remote: true
within the link_to
code, as the original poster was doing, will only look for a .js
format to respond with. As others have said, if you never need an html response, then you can remove that from your code all together; you won't even need a respond_to
, respond_with
, etc as Rails will auto respond with JS looking for the template you already have made. So your controller code would look like this:
def message
@user_id = params[:id]
@user = User.find_by_id(@user_id)
end
And the link would still be this:
<%=link_to "Message", message_user_path(:id => user.id), :remote => true %>
Or this would work as well (my preferred way of syntax):
<%=link_to "Message", message_user_path(id: user.id), remote: true %>
This code will call the controller action which will look for the template message.js.erb
.
I know this question is old now, but for anyone looking for answers and using current Rails 6+ (I'm using 7.0.0alpha), and if you are getting this same type of issue where both HTML and JS templates are being requested; check that turbolinks is not what is causing the issue. Sometimes turbolinks can cause a request to be sent twice and it may be sending the first request as an HTML request.
Upvotes: 0
Reputation: 1878
My solution was to replace
format.json do
with
format.js do
you can troubleshoot the request by setting a breakpoint (i use pry) in the controller and then look at the variable
request.format
Upvotes: 0
Reputation: 6096
Does your app/assets/javascripts/application.js
contain
//= require jquery
//= require jquery_ujs
?
And your erb contains <%= javascript_include_tag "application" %>
?
I was just struggling with a problem like this for HOURS and the last of those two points fixed it; I saw the first point mentioned in some other questions so I'll repeat it here.
Hope that helps.
Upvotes: 29
Reputation: 1437
What solver it for me was adding :format => "js"
So in your case:
<%=link_to "Message", message_user_path(:id => user.id, :format => "js"), :remote => true %>
Upvotes: 8
Reputation: 1716
In general, when you use link_to
on a particular button or so, when you press the button, as js
request is send to the controller, but also searches for the respective .js.erb file and so on.
Upvotes: 0