notaceo
notaceo

Reputation: 1093

Devise destroy session doesn't destroy the session?

Really new to devise - it's very frustrating in all honesty...

My user session isn't being destroyed.

Here is the link in my navbar:

<li><%= link_to 'Logout', destroy_user_session_path, :method => :delete %></li>

devise.rb has the :delete method configured:

# The default HTTP method used to sign out a resource. Default is :delete.
  config.sign_out_via = :delete

Route is:

  destroy_user_session DELETE /users/sign_out(.:format)             sessions#destroy

Application controller says :

class ApplicationController < ActionController::Base
  protect_from_forgery

  private
      def after_sign_out_path_for(resource_or_scope)
        root_path
      end

I click my sign out link and my console shows :

Started GET "/users/sign_out" for 127.0.0.1 at 2014-04-18 12:00:26 -0500
Processing by UsersController#show as HTML
  Parameters: {"id"=>"sign_out"}
MONGODB (0.8ms) waittext_development['users'].find({:_id=>BSON::ObjectId('53515685963e6507ad00003e')}).limit(-1)

It doesn't seem to be finding an active session (I've clicked it a dozen times in frustration), but the problem is the page I land out - UsersController#show - is not the page I've told it to route to. It should be the root_path which is users#index

So I was getting all these nil class errors on users#show because it was trying to render the default rails @user.name, etc. and @user isn't defined - I finally manually overrode the show action to simply render 'index' and I end up on my index page - BUT STILL - I'm seeing current_user.email printed here:

<% if user_signed_in? -%>
  <ul>
    <li><%= current_user.email %></li>
    <li><%= link_to 'My info', edit_user_registration_path %></li>
    <li><%= link_to 'Sign out', destroy_user_session_path %></li>
  </ul>

It is evaluating TRUE and I'm getting those three list items.

User should not be signed in because I just destroyed the session!

What the heck?

Upvotes: 1

Views: 4707

Answers (2)

Holger Just
Holger Just

Reputation: 55888

You issue a GET request, not a DELETE (or even a POST with a set _method parameter to emulate a proper DELETE). As such, your request is routed to UsersController#show which listens to GET /users/:id.

The reason for that is, that a plain HTML link normally can only lead to GET requests. For anything else, you need a form. If you now pass the :method parameter to the link_to method in your view, Rails will generate some Javascript which captures the click on the link to generate a form and send the request that way. This will fail if the user has Javascript disabled, which seems to be the case here.

You should thus either ensure that all users (including you) have Javascript enabled or use something like button_to instead which will create a proper form in HTML which works without Javascript.

Upvotes: 2

Abs
Abs

Reputation: 3962

This is how i have implemented this so known to work:

  devise_scope :user do
    match "sign_out", :to => "sessions#destroy", via: [:delete]
  end

<%= link_to sign_out_path, :method => "DELETE" do %>

<% end%>

Upvotes: 1

Related Questions