I am having an issue with Devise' before_action :authenticate_user!
filter on remote: true
option.
I have a link tag which makes a normal PUT request to messages#read
of my MessagesController
below
<%= link_to 'Mark Read/Unread', read_message_path(message), method: :put %>
class MessagesController < ApplicationController
before_action :authenticate_user!, only: :read
before_action :set_message, only: :read
...
#http PUT
def read
@message.toggle!(:read)
respond_to do |format|
format.html { redirect_to messages_url, notice: 'Message was successfully destroyed.' }
format.json { head :no_content }
end
end
...
end
If the user is not signed in, it redirects to the sign in page as the expected Devise behavior.
However when setting the remote: true
option on the link e.g.
<%= link_to 'Mark Read/Unread', read_message_path(message), method: :put, remote: true %>
Devise breaks with error: PUT http://localhost:3000/users/sign_in.js 404 (Not Found)
My logs output a 401 Unauthorized
followed by
ActionController::RoutingError (No route matches [PUT] "/users/sign_in.js")
The problem is Rails tries to render /users/sign_in.js
via PUT which does not exist and shouldn't. This is what trips me off and confuses me becasue I would exptect to be redirected to devise /users/sign_in
html page and instead Rails tries to render a sign_in page with .js
extension.
I tried setting config/initializers/devise.rb
lines to
config.http_authenticatable_on_xhr = false
config.navigational_formats = ['*/*', :html, :js]
as suggested here.
I am using Devise with its default settings. No special routes nor controllers.
What am I missing here? am I misunderstading the way Devise is supposed to work?
Is there away to override authenticate_user!
to redirect to devise' default sign_in html page on xhr requests?