No route matches "/users/sign_out" devise rails 3

Ruby on-RailsRuby on-Rails-3DeviseRoutes

Ruby on-Rails Problem Overview


I've installed devise on my app and applied the following in my application.html.erb file:

<div id="user_nav">
	<% if user_signed_in? %>
		Signed in as <%= current_user.email %>. This cannot be cheese?
		<%= link_to 'Sign out', destroy_user_session_path %>
	<% else %>
		<%= link_to 'Register', new_user_registration_path %> or <%= link_to 'Sign in', new_user_session_path %>
	<% end %>
</div>

I ran rake routes and confirmed that all the routes are valid.

Also, in my routes.rb file I have devise_for :users and root :to => "home#index".

I get the following routing error when clicking the "Sign out" link:

No route matches "/users/sign_out"

Any ideas what's causing the error?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

I think the route for signing out is a DELETE method. This means that your sign out link needs to look like this:

<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>

Yours doesn't include the :method => :delete part. Also, please note that for this to work you must also include <%= javascript_include_tag :defaults %> in your layout file (application.html.erb).

Solution 2 - Ruby on-Rails

I changed this line in devise.rb:

config.sign_out_via = :delete

to

config.sign_out_via = :get

and it started working for me.

Solution 3 - Ruby on-Rails

You probably didn't include jquery_ujs javascript file. Make sure you are using the latest version of jquery-ujs : https://github.com/rails/jquery-ujs and the last files available :

rails generate jquery:install

You should not have any more rails.js file. If you do, you're probably out-of-date. Make sure also this file is loaded with defaults, in config/application.rb

config.action_view.javascript_expansions[:defaults] = %w(jquery.min jquery_ujs)

(Again, you should not have rails.js file here). Finally, add the link as documented on Devise wiki (haml-style):

= link_to('Logout', destroy_user_session_path, :method => 'delete')

And everything will be fine.

Solution 4 - Ruby on-Rails

The ability to make the Logout link a DELETE RESTful call requires an html attribute data-method = "delete" by using the rails code = link_to('Logout', destroy_user_session_path, :method => :delete).

However, if you do not have the gem jquery-ujs installed or are not calling the resulting javascript in your application.html via = javascript_include_tag "application", the response will be sent as a GET request, and the route will fail.

You have a few options if you do not want to use jquery-ujs or cannot find a way to make it work:

  1. Change config.sign_out_via to equal :get within devise.rb (not recommended, since DELETE is the appropriate RESTful query)
  2. OR Change the link_to to = button_to('Logout', destroy_user_session_path, :method => :delete). With button_to Rails will do the heavy lifting on making the proper DELETE call. You can then style the button to look like a link if you wish.

Solution 5 - Ruby on-Rails

Try adding a new route to devise/sessions#destroy and linking to that. Eg:

routes.rb
devise_for :users do
  get 'logout' => 'devise/sessions#destroy'
end

view:

<%= link_to "Logout", logout_path %>

Solution 6 - Ruby on-Rails

Use it in your routes.rb file:

devise_for :users do
    get '/users/sign_out' => 'devise/sessions#destroy'
end

Solution 7 - Ruby on-Rails

I had the same problem with rails 3.1.0, and I solved adding in file the followings lines:

app/assets/javascripts/application.js
//= require_tree
//= require jquery
//= require jquery_ujs

Solution 8 - Ruby on-Rails

With one exception, Jessie's answer worked for me:

<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>

change:

:delete

... to:

'delete'

So the code that worked for me is:

<%= link_to "Sign out", destroy_user_session_path, :method => 'delete' %>

Solution 9 - Ruby on-Rails

Many answers to the question already. For me the problem was two fold:

  1. when I expand my routes:

     devise_for :users do 
        get '/users/sign_out' => 'devise/sessions#destroy'
     end
    
  2. I was getting warning that this is depreciated so I have replaced it with:

     devise_scope :users do
        get '/users/sign_out' => 'devise/sessions#destroy'
     end
    
  3. I thought I will remove my jQuery. Bad choice. Devise is using jQuery to "fake" DELETE request and send it as GET. Therefore you need to:

     //= require jquery
     //= require jquery_ujs
    
  4. and of course same link as many mentioned before:

     <%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
    

Solution 10 - Ruby on-Rails

Add:

  <%= csrf_meta_tag %>  and 
  <%= javascript_include_tag :defaults %>  to layouts

Use these link_to tags

 link_to 'Sign out', destroy_user_session_path, :method => :delete

  or

 link_to 'Sign out', '/users/sign_out', :method => :delete

In routes add:

  devise_for :users do
    get '/users/sign_out' => 'devise/sessions#destroy'
  end

Solution 11 - Ruby on-Rails

Other option is to configure the logout to be a GET instead a DELETE, you can do that adding the following line on /config/initializers/devise.rb

config.sign_out_via = :get

But as Steve Klabnik wrote on his blog (http://blog.steveklabnik.com/2011/12/11/devise-actioncontroller-routingerror-no-route-matches-get-slash-users-slash-sign-out.html) try to use DELETE because of the semantic of this method.

Solution 12 - Ruby on-Rails

If you are using Rails 3.1 make sure your application.html.erb sign out looks like:

<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>

And that your javascript include line looks like the following

<%= javascript_include_tag 'application' %>

My guess is that some gems overwrite the new structure of the default.js location.

Solution 13 - Ruby on-Rails

Check it out with source code in github:

https://github.com/plataformatec/devise/commit/adb127bb3e3b334cba903db2c21710e8c41c2b40#lib/generators/templates/devise.rb (date : June 27, 2011 )

  • The default HTTP method used to sign out a resource. Default is :get.

188

  • config.sign_out_via = :get

    187
  • The default HTTP method used to sign out a resource. Default is :delete.

    188
  • config.sign_out_via = :delete

Solution 14 - Ruby on-Rails

Well, guys for me it was only remove the :method => :delete

<%= link_to('Sign out', destroy_user_session_path) %>

Solution 15 - Ruby on-Rails

I want to add to this even though it's a bit old.

the "sign_out" link didn't work, despite having :method => :delete.

The comment indicating that <%= javascript_include_tag :defaults %> must be included reminded me I had recently added JQuery java script and used simple <script src=""/> tags to include them.

When I moved them from after the :defaults to before, the sign_out started working again.

Hopefully this helps someone.

Solution 16 - Ruby on-Rails

This means you haven't generated the jquery files after you have installed the jquery-rails gem. So first you need to generate it.

rails generate devise:install

First Option:

This means either you have to change the following line on /config/initializers/devise.rb

config.sign_out_via = :delete to config.sign_out_via = :get

Second Option:

You only change this line <%= link_to "Sign out", destroy_user_session_path %> to <%= link_to "Sign out", destroy_user_session_path, :method => :delete %> on the view file.

Usually :method => :delete is not written by default.

Solution 17 - Ruby on-Rails

Don't forget to include the following line in your application.js (Rails 3)

//= require_self
//= require jquery
//= require jquery_ujs

Include jquery_ujs into my rails application and it works now.

Solution 18 - Ruby on-Rails

Most answers are partial. I have hit this issue many times. Two things need to be addressed:

<%= link_to(t('logout'), destroy_user_session_path, :method => :delete) %>

the delete method needs to be specified

Then devise uses jquery, so you need to load those

   <%= javascript_include_tag "myDirectiveJSfile" %> 

and ensure that BOTH jquery and jquery-ujs are specified in your myDirectiveJSfile.js

//= require jquery
//= require jquery_ujs

Solution 19 - Ruby on-Rails

If you're using HTTPS with devise, it'll break if your sign-out link is to the non-secure version. On the back end, it redirects to the secure version. That redirect is a GET, which causes the issue.

Make sure your link uses HTTPS. You can force it with protocol: "https" in your url helper (make sure you use the url helper and not the path helper).

<%= link_to "Sign out", destroy_user_session_url(protocol: "https"), method: :delete %>

Solution 20 - Ruby on-Rails

  devise_for :users
  devise_scope :user do
    get '/users/sign_out' => 'devise/sessions#destroy'
  end

Solution 21 - Ruby on-Rails

The problem begin with rails 3.1... in /app/assets/javascript/ just look for application.js.

If the file doesn't exist create a file with that name I don't know why my file disappear or never was created on "rails new app"....

That file is the instance for jquery....

Solution 22 - Ruby on-Rails

Lots of solutions are there. but mostly use this,

<%= link_to 'Sign out', destroy_user_session_path, method: :delete %>

or config devise.rb with proper sign_out method

In devise.rb

config.sign_out_via = :delete ( or  :get which u like to use.) 

Solution 23 - Ruby on-Rails

use :get and :delete method for your path:

devise_scope :user do
  match '/users/sign_out' => 'devise/sessions#destroy', :as => :destroy_user_session, via: [:get, :delete]
end

Solution 24 - Ruby on-Rails

This is what I did (with Rails 3.0 and Devise 1.4.2):

  1. Make sure your page loads rails.js
  2. Use this param: 'data-method' => 'delete'
  3. Good idea to add this param: :rel => 'nofollow'

Solution 25 - Ruby on-Rails

In your routes.rb :

 devise_for :users do
    get '/sign_out' => 'devise/sessions#destroy'
    get '/log_in' => 'devise/sessions#new'
    get '/log_out' => 'devise/sessions#destroy'
    get '/sign_up' => 'devise/registrations#new'
    get '/edit_profile' => 'devise/registrations#edit'
 end

and in your application.html.erb:

<%if user_signed_in?%>
          <li><%= link_to "Sign_out", sign_out_path %></li>
<% end %>

Solution 26 - Ruby on-Rails

See if your routes.rb has a "resource :users" before a "devise_for :users" then try swapping them:

  1. Works
  • devise_for :users
  • resources :users
  1. Fails
  • resources :users
  • devise_for :users

Solution 27 - Ruby on-Rails

the ':method => :delete' in page is 'data-method="delete"' so your page must have jquery_ujs.js, it will submit link with method delete not method get

Solution 28 - Ruby on-Rails

I know this is an old question based on Rails 3 but I just ran into and solved it on Rails 4.0.4. So thought I'd pitch in how I fixed it for anyone encountering this problem with this version. Your mileage may vary but here's what worked for me.

First make sure you have the gems installed and run bundle install.

gem 'jquery-rails'

gem 'turbolinks'

gem 'jquery-turbolinks'

In application.js check that everything is required like below.

Beware if this gotcha: it's //= require jquery.turbolinks and not //= require jquery-turbolinks

//= require jquery
//= require jquery_ujs
//= require jquery.turbolinks
//= require turbolinks
//= require_tree .

Next, add the appropriate links in the header of application.html.erb.

<%= javascript_include_tag  "application", "data-turbolinks-track" => true %>
<%= javascript_include_tag :defaults %>

There seems to be many variations on how to implement the delete method which I assume depends on the version of Rails you are using. This is the delete syntax I used.

<p><%= link_to "Sign Out", destroy_user_session_path, :method => 'delete' %></p>

Hope that helps dig someone out of this very frustrating hole!

Solution 29 - Ruby on-Rails

In general when you get "No route matches" but you think you have that route defined then double check the http verb / request method (whether its get, put, post, delete etc.) for that route.

If you run rake routes then you will see the expected method and you can compare this with the request log.

Solution 30 - Ruby on-Rails

I am using rails 7. So This was how I had to do it. The important bit is data: { turbo_method: :delete }

<%= link_to t('nav.logout'), destroy_user_session_path, class: "nav-link", data: { turbo_method: :delete } %>

Below were the defaults created by rails when I generated the project.

application.html.erb

<%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>

application.js

import "@hotwired/turbo-rails"
import "./controllers"
import * as bootstrap from "bootstrap"

Solution 31 - Ruby on-Rails

For Rails 7

We importmap the jquery and jquery-ujs manually in the importmap.rb :

pin "jquery", to: "https://ga.jspm.io/npm:[email protected]/dist/jquery.js"
pin "jquery-ujs", to: "https://cdnjs.cloudflare.com/ajax/libs/jquery-ujs/1.2.3/rails.min.js"

or for jquery use the:

./bin/importmap pin jquery

and enter manually the 2nd line for jquery-ujs

We create the file: app/javascript/src/jquery.js with the code:

import jquery from 'jquery'
window.jQuery = jquery
window.$ = jquery

Then we import them inside the app/javascript/application.js :

import "src/jquery"
import "jquery-ujs"

and we're done without having to change the config.sign_out_via = :delete of devise.rb

** Notice: For jquery it may require a yarn add jquery if for some reason the above doesn't work

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionvichView Question on Stackoverflow
Solution 1 - Ruby on-RailsJessie DedeckerView Answer on Stackoverflow
Solution 2 - Ruby on-RailskitdesaiView Answer on Stackoverflow
Solution 3 - Ruby on-RailsGravisView Answer on Stackoverflow
Solution 4 - Ruby on-RailsWill NathanView Answer on Stackoverflow
Solution 5 - Ruby on-RailsKevin TsoiView Answer on Stackoverflow
Solution 6 - Ruby on-RailsUma MaheswararaoView Answer on Stackoverflow
Solution 7 - Ruby on-RailsgringoView Answer on Stackoverflow
Solution 8 - Ruby on-RailsGalenView Answer on Stackoverflow
Solution 9 - Ruby on-RailsLukasz MuzykaView Answer on Stackoverflow
Solution 10 - Ruby on-RailsAmal Kumar SView Answer on Stackoverflow
Solution 11 - Ruby on-RailsRodrigo FloresView Answer on Stackoverflow
Solution 12 - Ruby on-RailsStlTennyView Answer on Stackoverflow
Solution 13 - Ruby on-RailsShaneView Answer on Stackoverflow
Solution 14 - Ruby on-RailsworkdreamerView Answer on Stackoverflow
Solution 15 - Ruby on-RailsGregView Answer on Stackoverflow
Solution 16 - Ruby on-RailsDeepak LamichhaneView Answer on Stackoverflow
Solution 17 - Ruby on-RailsThe Lazy LogView Answer on Stackoverflow
Solution 18 - Ruby on-RailsJeromeView Answer on Stackoverflow
Solution 19 - Ruby on-RailsTyler CollierView Answer on Stackoverflow
Solution 20 - Ruby on-Railsdipole_momentView Answer on Stackoverflow
Solution 21 - Ruby on-Railsrome3roView Answer on Stackoverflow
Solution 22 - Ruby on-Railsjon snowView Answer on Stackoverflow
Solution 23 - Ruby on-RailsZakariaView Answer on Stackoverflow
Solution 24 - Ruby on-RailsLarryView Answer on Stackoverflow
Solution 25 - Ruby on-RailsUladz KhaView Answer on Stackoverflow
Solution 26 - Ruby on-RailsCharles MagidView Answer on Stackoverflow
Solution 27 - Ruby on-Railsuser1599712View Answer on Stackoverflow
Solution 28 - Ruby on-RailsmikeymView Answer on Stackoverflow
Solution 29 - Ruby on-RailsMuntasimView Answer on Stackoverflow
Solution 30 - Ruby on-RailsantonkronajView Answer on Stackoverflow
Solution 31 - Ruby on-RailsFilipposView Answer on Stackoverflow