I'm using devise for user authentication. In my views I've set:
<% if user_signed_in? %>
<li><%= link_to "Log Out", destroy_user_session_path %></li>
<% else %>
<li><%= link_to "Sign In", new_user_session_path %></li>
<% end %>
However when I click Log_Out I'm getting an error:
No route matches [GET] "/users/sign_out"
However when I check my rake routes I'm getting:
devise/sessions#destroy destroy_user_session DELETE /users/sign_out(.:format)
What apneadiving said.
<%= link_to "Log Out", destroy_user_session_path, method: :delete %>
Default sign out is use "delete" method. Your route also said the method is “DELETE"
If you want use "get" method
Modify devise.rb to
config.sign_out_via = :get
Baloo is right, make sure to use the :delete method. You can see this clearly if you invoke
rake routes
You'll see the path as well as the method.
Related
I'm following the Rails Tutorial by Michael Hartl to build a tiny demo app. I'm stuck at the logout. This is my routes.rb:
Rails.application.routes.draw do
resources :users
get "/login", to: "sessions#new"
post "/login", to: "sessions#create"
delete "/logout", to: "sessions#destroy"
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
# Defines the root path route ("/")
root 'users#index'
end
This is the relevant controller action:
def destroy
log_out
redirect_to root_url, status: :see_other
end
This is the session helper defining log_out:
def log_out
reset_session
#current_user = nil
end
and this is the link tag in the view:
<%= link_to "Log out", logout_path, data: { 'turbo-method': :delete } %></span>
Screenshot of error
When I click on the logout link, I get this error. Expected behaviour: Log user out, redirect to login screen.
What am I doing wrong?
I don't know whether it's because of Turbo, or whether Turbo is even correctly installed. I've added gem 'turbo-rails' to the Gemfile and ran bundle afterwards without any effect.
For me, adding the method: :delete worked along with data-turbo.
<span>
<%= link_to "Log out", destroy_user_session_path,method: :delete, data: { 'turbo-method': :delete } %></span>
You were accessing the DELETE method route via GET. Have you run
rails turbo:install
You may want to change the sign out via GET instead of Delete in config/devise.rb
# The default HTTP method used to sign out a resource. Default is :delete.
config.sign_out_via = :get # <= change this from :delete to :get and remove the `method:` in your `link_to` helper
Here's the references:
https://github.com/hotwired/turbo-rails
https://github.com/heartcombo/devise/issues/5439
Check with passing method
<%= link_to "Log out", logout_path, method: :delete, data: { 'turbo-method': :delete } %>
or
<%= link_to "Log out", logout_path, method: :delete %>
You can change link_to to button_to
<%= button_to "Log out", logout_path, method: :delete %>
It will be less magic but more reliable because not a link but form is used (in normal life, clicking on link is a GET request)
I am running Rails 5 and updated Bootstrap to version 4 in an existing app which uses Devise.
Before updating Bootstrap, the routes were working fine. Now, when the user selects sign-out, they receive the following message:
No route matches [GET] "/users/sign_out"
Here is part of the header code:
<% if current_user %>
<a class=<%= link_to 'Classes', tracks_path %></a>
<a class=<%= link_to 'Edit profile', edit_user_registration_path %></a>
<a class=<%= link_to 'Sign out', destroy_user_session_path, method: :delete %></a>
And Rake Routes shows:
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
Is there a reason that the change to Bootstrap 4 would trigger this error? I have followed all of the instructions on the Bootstrap repo for installation.
The problem is you're rendering your link tags inside the class attribute:
<a class=<%= link_to 'Sign out', destroy_user_session_path, method: :delete %></a>
So that results in malformed output which ignores that you specify method: :delete. This is what you're looking for:
<%= link_to "Sign out", destroy_user_session_path,
method: :delete, class: 'nav-link' %>
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?
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.
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%>
I have a rails 3 app, and when I click the link to my terms page, it routes to a completely different controller, than what the routes should use. Stranger still, the route works when I'm not logged in, and I'm using devise.
I get this error when clicking the link when I'm logged in.
No route matches {:action=>"edit", :controller=>"users", :id=>nil}
<%= link_to "Terms", terms_path %>
Routes (in the order they appear in routes.rb):
devise_for :users, :controllers => {:registrations => "registrations"}
resources :users do
member do
get :following, :followers
post :accept
end
end
match '/terms', to: 'static_pages#user_agreement'
Static Pages Controller
def user_agreement
end
Rake Routes
terms /terms(.:format) static_pages#user_agreement
This also happens for every other action that I've routed this way to the staticpages controller, but not for any other actions that route to different controller.
Update: Terms Page
Header:
<%= link_to "Follow", users_path %>
<%= link_to current_user.name, current_user %>
<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
Footer:
<%= link_to "Welcome", welcome_path %>
<%= link_to "Settings", edit_user_path(#user) %>
<%= link_to "Terms", terms_path %>
All the content is pure html.
Thanks in advance
You have a link to edit_user_path with no #user as hinted in the comments.
You should almost certainly be using current_user anyway.
I've searched for an answer to this and nothing has helped.
I have the following in my view:
<div id="user_nav">
<% if user_signed_in? %>
Logged in as <strong><%= current_user.first_name + " " +current_user.last_name%></strong>.
<%= link_to 'Edit profile', edit_user_registration_path %> |
<%= link_to "Logout", destroy_user_session_path, method: :delete %>
<% else %>
<%= link_to "Sign up", new_user_registration_path %> |
<%= link_to "Login", new_user_session_path %>
<% end %>
Which is straight from the railscast on devise. Suddenly the paths are not working anymore. (sign up or sign in) for example when I click login i get the error
No route matches {:controller=>"devise/home", :action=>"students"}
Ive tried using <%= link_to "Login", :controller => '/devise/sessions', :action => 'new' %> jsut for kicks and it returns the same error.
Yes I have devise_for :users in my route file.
rake routes return all the right routes including
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
Any help would be awesome! I'm stumped!
Looking at my stack trace, something (a link) in my layout was throwing it off. I created a custom layout for devise and everything works fine now.