This question already has answers here:
No route matches "/users/sign_out" devise rails 3
(31 answers)
Closed 8 years ago.
Noob here building my first Rails 4.0 app using Devise. Set up my controller and routes using the standard Devise tactics.
Rake Routes shows:
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
In my Nav, my code is:
<%= link_to "Sign Out", destroy_user_session_path, method: :destroy, data: { confirm: 'Are you sure?' } %>
I'm running the Guard gem so my server is always on, so I know it's not a mismatch b/w my routes and the server. I still get the following error:
No route matches [POST] "/users/sign_out"
Any suggestions? Thanks all!
You probably need to change the method (http verb) option to delete:
<%= link_to "Sign Out", destroy_user_session_path, method: :delete, data: { confirm: 'Are you sure?' } %>
Check in config/initializers/devise.rb and make sure this is set:
config.sign_out_via = :delete
Also, in the view I have this and works just fine:
<%= link_to 'Logout', destroy_user_session_path, :method=>'delete' %>
Related
My View:
<%= link_to 'delete account', user_registration_path, :method => :delete, :class=>
'delete_account_button', data: {:confirm =>'sure?', disable_with: "deleting..."} %>
and I'm redirected to localhost:3000/users ... nothing more. No console errors, logs just show that I was redirected ...
FIRST WORKING EXAMPLE:
Changed link_to to button_to and it work. Why?
From the rails guides, you need a data turbo method to make it work
<%= link_to "Destroy", article_path(#article), data: {
turbo_method: :delete,
turbo_confirm: "Are you sure?"
} %>
So update from data key with something similar
data: { 'turbo-method': :delete, 'turbo-confirm': 'Are you sure?' }
turbo documentation
button_to
Is used to submit a form and send either a POST or DELETE request
link_to
Is used redirect_to a page through GET requests
Turbo is not necessary here to make the button work. However if you wanted to reload elements on the dom you would need turbo.
Check this tutorial out if you want to learn turbo and Hotwire for Rails 7.
https://www.hotrails.dev/turbo-rails
It helped me out a lot
I am trying to get this link to work, performing a DELETE request:
<%= link_to "Sign Out", destroy_user_session_path, method: :delete %>
However when I click on it, my browser still performs a GET request (which fails for obvious reasons):
I have read on multiple other forum posts, that this might have something to do with jquery not being included. They mentioned you would need to un-comment a line in app/javascript/application.js, however mine is pretty empty:
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "#hotwired/turbo-rails"
import "controllers"
These forum posts were also quite old, so I suspect something has changed in the meantime.
As suggested here, the following will suffice:
<%= link_to "Sign Out", destroy_user_session_path, data: { "turbo-method": :delete } %>
I have tested this in my project and it seems to work fine. Thanks also to #alexts, you basically figured this out too, however the comment on GitHub even eliminated the double-request.
There are (at least) two ways to delete something in rails 7:
Using button_to (preferred IMHO):
<%= button_to 'Sign Out', destroy_user_session_path, method: :delete %>
Renders an HTML form which sends a POST request with a hidden _method attribute with 'delete' value. Rails will treat this as if it has a DELETE method (and route it to products#destroy or whatever your routes are saying). Do not use this one within another form (HTML forbids one form inside another).
Using link_to:
<%= link_to 'Sign Out', destroy_user_session_path, data: {turbo_method: :delete} %>
Renders a simple a tag with data-turbo-method attribute. This link sends a real DELETE request.
If your destroy action ends with a redirect_to, some browsers will redirect to a new location with DELETE method (causing errors), so make sure to add status: :see_other parameter to redirect_to, like the guides suggest.
Confirmation
If you want to add confirmation prompt to a button above:
<%= button_to 'Sign Out', destroy_user_session_path, method: :delete,
form: {data: {turbo_confirm: 'Are you sure?'}} %>
If you want to add confirmation to a link above:
<%= link_to 'Sign Out', destroy_user_session_path,
data: {turbo_method: :delete, turbo_confirm: 'Are you sure?'} %>
Found it on git
Run these commands
It worked for me.
$ rails importmap:install
$ rails turbo:install stimulus:install
method: :delete just add a attribute
in order to make it useful, rails_ujs library is responsible
try to include it
that can be useful
I am trying to get this link to work, performing a DELETE request:
<%= link_to "Sign Out", destroy_user_session_path, method: :delete %>
However when I click on it, my browser still performs a GET request (which fails for obvious reasons):
I have read on multiple other forum posts, that this might have something to do with jquery not being included. They mentioned you would need to un-comment a line in app/javascript/application.js, however mine is pretty empty:
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "#hotwired/turbo-rails"
import "controllers"
These forum posts were also quite old, so I suspect something has changed in the meantime.
As suggested here, the following will suffice:
<%= link_to "Sign Out", destroy_user_session_path, data: { "turbo-method": :delete } %>
I have tested this in my project and it seems to work fine. Thanks also to #alexts, you basically figured this out too, however the comment on GitHub even eliminated the double-request.
There are (at least) two ways to delete something in rails 7:
Using button_to (preferred IMHO):
<%= button_to 'Sign Out', destroy_user_session_path, method: :delete %>
Renders an HTML form which sends a POST request with a hidden _method attribute with 'delete' value. Rails will treat this as if it has a DELETE method (and route it to products#destroy or whatever your routes are saying). Do not use this one within another form (HTML forbids one form inside another).
Using link_to:
<%= link_to 'Sign Out', destroy_user_session_path, data: {turbo_method: :delete} %>
Renders a simple a tag with data-turbo-method attribute. This link sends a real DELETE request.
If your destroy action ends with a redirect_to, some browsers will redirect to a new location with DELETE method (causing errors), so make sure to add status: :see_other parameter to redirect_to, like the guides suggest.
Confirmation
If you want to add confirmation prompt to a button above:
<%= button_to 'Sign Out', destroy_user_session_path, method: :delete,
form: {data: {turbo_confirm: 'Are you sure?'}} %>
If you want to add confirmation to a link above:
<%= link_to 'Sign Out', destroy_user_session_path,
data: {turbo_method: :delete, turbo_confirm: 'Are you sure?'} %>
Found it on git
Run these commands
It worked for me.
$ rails importmap:install
$ rails turbo:install stimulus:install
method: :delete just add a attribute
in order to make it useful, rails_ujs library is responsible
try to include it
that can be useful
I'm a bit confused about how devise is routing my requests, for some reason I can't go to the sign-out path in my app now:
ActionController::RoutingError (No route matches [GET] "/users/sign_out")
Here is what my routes related to my User model and Devise look like:
devise_for :users, :controllers => {:registrations => "registrations"}
devise_scope :user do
get '/settings' => 'registrations#edit'
end
Would defining that scope prevent my other routes from working as well?
Update
I don't think that it's supposed to be GET request, as my link looks like:
<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
If you try to go to /users/sign_out by typing it in the address bar of your browser, or linking to it normally, you will get this error. To summarize some comments and answers here and from issues at the devise repo on github:
This is the intended functionality, RESTful apps should not modify state with a GET request.
You can fix this by making a link that uses the DELETE method as mentioned by #Trip, #fuzzyalej, and the update by #Joseph Silvashy.
Alternatively, (and less recommended), in /config/initializers/devise.rb, you could make the following change
config.sign_out_via = :delete
to
config.sign_out_via = :get
I came across this issue while following along with http://railscasts.com/episodes/209-introducing-devise and with the older version of devise he's using there, this was not an issue.
Keep your devise.rb using the correct HTTP method:
# good
config.sign_out_via = :delete
# bad
config.sign_out_via = :get
Use button_to instead of link_to
# good
= button_to "Sign Out", destroy_user_session_path, method: :delete
# bad
= link_to "Sign Out", destroy_user_session_path, method: :delete"
If you are using bootstrap (keep it classy)
= link_to "Sign Out", destroy_user_session_path, method: :delete, class: "btn btn-default btn-sm"
Just so this post has an answer :
This must be sent with the method, delete so that it does not default to a get
<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
devise_for :users
devise_scope :user do
get '/users/sign_out' => 'devise/sessions#destroy'
end
in your routes.rb.
If you're using SSL with Devise controllers, and trying to sign out from an 'http' url, what's happening is it's sending the DELETE request to the #destroy method, but then redirecting to the https version via GET. You can fix this by adding the https to the sign out link like so:
= link_to "Sign out", destroy_user_session_url(protocol: 'https'), method: :delete
Note: must be 'url' instead of 'path'
in Rails 7 the destroy_user_session_path changes a bit on the method.
instead of using the traditional method: :delete that came with the jquery and rails_ujs. Now you need to change that to ..., data: {turbo_method: :delete} and you don't need to setup any additional rails_ujs or jquery
From the rails documentation:
link_to("Destroy", "http://www.example.com", :method => :delete, :confirm => "Are you sure?")
# => Destroy
I had the same problem and to solve it took these steps:
1) include the //= require jquery_ujs in the assets/javascripts/application.js
2) add gem 'jquery-rails' to my gemfile
3) bundle install
... and it worked.
I am using the devise gem to make authentication work in my app.
Here's the code I have for signing out:
<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
I have tried this as well:
<%= link_to "Sign out", destroy_user_session_path%>
Both of which when I click on sign out I get :
No route matches [GET] "/users/destroy"
However when I run rake routes, you can see it (just not GET):
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
How to fix this?
Mitch's answer was close but did not work for me, instead the following syntax did:
<%= link_to "Log out", destroy_user_session_path, :method => :delete %>
Could this help you in the right direction?
https://github.com/plataformatec/devise/issues/1195
Roger's link above is v useful.
I used the following syntax, which worked:
<%= link_to "Log out", destroy_session_path(:user), :method => :delete %>