Devise, can't log out - devise

In a Rails app, I use devise to manage my users and my link to destroy a session no longer work. It was working, and now I have add active admin, It doesn't.
My link is
<%= link_to "Déconnexion", destroy_user_session_path, :method => :delete, :class => 'button' %>
My routes.rb
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks"}
My rake routes
destroy_user_session DELETE /users/sign_out(.:format)
And it try to open the view /users/sign_out, so I have :
ActiveRecord::RecordNotFound in UsersController#show
Couldn't find User with id=sign_out
Does Active_admin and Devise crash together?
It will be weird 'cause active use devise, no?
Edit:
For the next person who will have this issue, I solved it by adding the next line to /config/initializers/devise.rb.
config.sign_out_via = :get
Not exactly the finest way, but it does the job.

Posting Jeff Paquette's comment as an answer.
Update the config/initializers/active_admin.rb with:
config.logout_link_method = :delete

Please make changes in your routes.rb :-
devise_scope :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks"} do
get "/users/sign_out", :to => "devise/sessions#destroy"
end
I am also getting same problem, only this can resolve me after 1hr time wasting.
Thanks.

Related

Update users details without a password by admin. Rails 3.x Devise

I would like to create a link to approve a users signup,
1) First solution<%= link_to "Approve", edit_user_registration_path(:id => user.id, :approved => true), :method => :put %>
However it drops back No route matches [PUT] "/users/edit"
2) Also I was thinking about an extra action that will respond to a specific route and update the user signup, say match '/users/approve_user', :controller => 'users', :action => 'approve_user', :collection => { :my_action => :put}
and in the view:
%- link_to "Approve", users_approve_user_path(:id => user.id), :method => :put
However, it gives back that Couldn't find User with ID=approve_user
Any help will be appreciated
I think you should use custom routing with devise
This is direct from devise documentation (https://github.com/plataformatec/devise), configuring routes
devise_scope :user do
get "sign_in", :to => "devise/sessions#new"
end
so in your case try something like
devise_scope :user do
post "Approve", :to => "users/approve_user"
end
and please note, by default device users controller comes under the name space 'devise'.

Unable to delete resource after overriding devise registrations controller

I have followed this devise how to: Redirect to a specific page on successful sign up.
I have created a new RegistrationsController
class RegistrationsController < Devise::RegistrationsController
def after_inactive_sign_up_path_for(resource)
...
end
def destroy
logger.debug 'destroy user'
...
end
end
I have changed routes.rb :
devise_for :users, :controllers => { :registrations => "registrations" } do
get 'users', :to => 'profile#index', :as => :user_root
end
and moved devise/registrations/ views under my new RegistrationsController.
With rake routes I have :
DELETE /users(.:format) {:action=>"destroy", :controller=>"registrations"}
after_inactive_sign_up_path_for is working.
But destroy action doesn't work : when I cancel my account
<%= button_to "Cancel my account", registration_path(resource_name), :confirm => "ok?", :method => :delete %>
I have the following error :
The action 'destroy' could not be found for RegistrationsController
I use Devise 1.4.5 & Rails 3.1
I just ran into the same issue. Moving the destroy method to the non private section of the controller fixed it.

Rails Devise not Deleting Account

I am starting a new web app and I am using Devise for the authentication.
I have got Devise working with register, login, edit and viewing the user profile. The only problem I am having is clicking the 'Delete Account' just redirects to /users and doesn't actually delete the user. What am I doing wrong?
The delete account button
= link_to "Cancel my account", registration_path(resource_name), :confirm => "Are you sure?", :method => :delete
As far as I know, I haven't changed anything that would break this. The delete account button I want to use is
= negative_trash_button_link_to "Cancel my account", registration_path(resource_name), :method => :delete, :confirm => "You sure?"
The negative_trash_button_link_to is in the css3buttons gem.
Edit: My routes.rb
resources :posts
ActiveAdmin.routes(self)
devise_for :admin_users, ActiveAdmin::Devise.config
root :to => "home#index"
devise_for :users do
get "/users/sign_out" => "devise/sessions#destroy", :as => :destroy_user_session
end
resources :users, :only => :show
It would be helpful to tell us the rails version and the javascript libraries / frameworks that you have installed.
If you are using jquery or any other framework is working, test if it is working in general if is is using the appropriate helpers (for example the jquery-rails helpers in case of jquery). Most probably is a javascript issue, check also for any javascript errors.
Look your javascript console. You seems to have a javascript error which prevent the request to be sent.
Do you have the alert "Are you sure?" before the redirection ?

Trying to create a POST request but getting No route matches [GET]

I'm trying to do something similar to Railscasts #255 but I'm getting a No Route error:
In Ryan's routes.rb file:
post "versions/:id/revert" => "versions#revert", :as => "revert_version"
In in the controller where he uses the route, versions_controller.rb
link = view_context.link_to(link_name, revert_version_path(#version.next, :redo => !params[:redo]), :method => :post)
redirect_to :back, :notice => "Undid #{#version.event}. #{link}"
In my routes.rb
post "/approve/:id" => "listings#approve", :as => "listing_approve"
and view where I use my link:
<%= link_to 'Approve Content', listing_approve_path(#listing), :method => :post %>
My tests return to me a ActionController::RoutingError: No route matches [GET] "/approve/1"
If I leave the method as a GET everything works.. Using rails 3.1.0rc5. Any guidance as to what I'm doing wrong here would be very much appreciated..
EDIT: routes.rb file (the last line is set as match right now to work)
RLR::Application.routes.draw do
root :to => "home#index"
devise_for :users, :controllers => { :registrations => "registrations" }
devise_for :users
match '/user' => "layouts#index", :as => :user_root
resources :users, :only => :show
resources :layouts, :only => [:index, :show]
resources :listings
resources :features
resources :orders
match "/preview/:id" => "listings#preview", :as => "listing_preview", :via => "get"
match "/approve/:id" => "listings#approve", :as => "listing_approve"
end
Hmmmm, it looks right to my eye. The test sounds like it is generating a GET instead of a POST though, so it might be a problem with the link_to call. You've got :method => :post there, so it should be fine. http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to seems to indicate that link_to will generate some javascript to make a POST call on click (and that users with javascript disabled will get a normal GET link unless you use :href="#"), so it might be because your test engine isn't running the javascript.
You can fix this by changing it to a button that submits a hidden form, but that might not be the visual representation you want.
It might be a precedence thing - the first matching route definition in routes.rb is used, so if you have a resources route or something like that it may be matching on that first.
I got the same problem in my rails application and I solved it the same way you did by doing a via: :get on the match instead of a via: :post. I think for some reason when you send a request in the format of /something/:id it will automatically assume its a [GET] request and search for a get route. This of course will cause problems in your routes if you have it as a :POST.
If anyone has a better solution or idea as to why you cannot send a post request in the format '/something/:id' let me know please.

No route matches [GET] "/users/sign_out"

Here is my actual error: No route matches [GET] "/members/sign_out"
Since most people will use "users" I thought it would be more helpful to have that in the title. At any rate, I am essential unable to logout. I can successfully edit my member profile.
I am using devise 1.4.2 and Rails 3.1.0.rc4. Also, I have generated two separate devise models - one called "members" and the other called "admins". I was able to register and log into both of them (simultaneously) by manually navigating to the correct URL path (i.e., localhost:3000/admins/sign_in/). I created some links within my application.html.haml layout file by following this RailsCast on Devise. I am aware that it only addresses signin/signout links for "members."
If I click on the signout link I get the above error. This occurs if I manually navigate to either signout URL (i.e., localhost:3000/admins/sign_out/).
Can someone tell me why this is happening? Below are the various related files. And of course, I'm a newbie...
rake routes output:
j(film_repo)$ rake routes
new_member_session GET /members/sign_in(.:format) {:action=>"new", :controller=>"devise/sessions"}
member_session POST /members/sign_in(.:format) {:action=>"create", :controller=>"devise/sessions"}
destroy_member_session DELETE /members/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"}
member_password POST /members/password(.:format) {:action=>"create", :controller=>"devise/passwords"}
new_member_password GET /members/password/new(.:format) {:action=>"new", :controller=>"devise/passwords"}
edit_member_password GET /members/password/edit(.:format) {:action=>"edit", :controller=>"devise/passwords"}
PUT /members/password(.:format) {:action=>"update", :controller=>"devise/passwords"}
cancel_member_registration GET /members/cancel(.:format) {:action=>"cancel", :controller=>"devise/registrations"}
member_registration POST /members(.:format) {:action=>"create", :controller=>"devise/registrations"}
new_member_registration GET /members/sign_up(.:format) {:action=>"new", :controller=>"devise/registrations"}
edit_member_registration GET /members/edit(.:format) {:action=>"edit", :controller=>"devise/registrations"}
PUT /members(.:format) {:action=>"update", :controller=>"devise/registrations"}
DELETE /members(.:format) {:action=>"destroy", :controller=>"devise/registrations"}
new_admin_session GET /admins/sign_in(.:format) {:action=>"new", :controller=>"devise/sessions"}
admin_session POST /admins/sign_in(.:format) {:action=>"create", :controller=>"devise/sessions"}
destroy_admin_session DELETE /admins/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"}
admin_password POST /admins/password(.:format) {:action=>"create", :controller=>"devise/passwords"}
new_admin_password GET /admins/password/new(.:format) {:action=>"new", :controller=>"devise/passwords"}
edit_admin_password GET /admins/password/edit(.:format) {:action=>"edit", :controller=>"devise/passwords"}
PUT /admins/password(.:format) {:action=>"update", :controller=>"devise/passwords"}
cancel_admin_registration GET /admins/cancel(.:format) {:action=>"cancel", :controller=>"devise/registrations"}
admin_registration POST /admins(.:format) {:action=>"create", :controller=>"devise/registrations"}
new_admin_registration GET /admins/sign_up(.:format) {:action=>"new", :controller=>"devise/registrations"}
edit_admin_registration GET /admins/edit(.:format) {:action=>"edit", :controller=>"devise/registrations"}
PUT /admins(.:format) {:action=>"update", :controller=>"devise/registrations"}
DELETE /admins(.:format) {:action=>"destroy", :controller=>"devise/registrations"}
films GET /films(.:format) {:action=>"index", :controller=>"films"}
POST /films(.:format) {:action=>"create", :controller=>"films"}
new_film GET /films/new(.:format) {:action=>"new", :controller=>"films"}
edit_film GET /films/:id/edit(.:format) {:action=>"edit", :controller=>"films"}
film GET /films/:id(.:format) {:action=>"show", :controller=>"films"}
PUT /films/:id(.:format) {:action=>"update", :controller=>"films"}
DELETE /films/:id(.:format) {:action=>"destroy", :controller=>"films"}
root / {:controller=>"films", :action=>"index"}
routes.rb
FilmRepo::Application.routes.draw do
devise_for :members
devise_for :admins
resources :films
root :to => 'films#index'
end
admin.rb (model)
class Admin < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, and :omniauthable
devise :database_authenticatable, :registerable, :timeoutable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
end
member.rb (model)
class Member < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
end
application.html.haml
!!!
%html
%head
%title Film Repo
= stylesheet_link_tag 'compiled/screen.css', :media => 'screen, projection'
= stylesheet_link_tag 'compiled/print.css', :media => 'print'
/[if lt IE 8]
= stylesheet_link_tag 'compiled/ie.css', :media => 'screen, projection'
= csrf_meta_tag
%body.bp
#container
#user_nav
- if member_signed_in?
Signed in as #{current_member.email}. Not you?
\#{link_to "Sign out", destroy_member_session_path}
- else
= link_to "Sign up", new_member_registration_path
or #{link_to "sign in", new_member_session_path}
- flash.each do |name, msg|
= content_tag :div, msg, :id => "flash_#{name}"
= yield
You can end a session via get by changing the devise configuration in initializers.
# The default HTTP method used to sign out a resource. Default is :delete.
config.sign_out_via = :get
Just open the link and your session is removed.
I had a similar problem, but addition of the :method=> :delete didn't work.
I was able to add a new route for a the get request by commenting out the devise_for :users and adding
devise_for :users do
get '/users/sign_out' => 'devise/sessions#destroy'
end
I had a similar problem.
My view code was like this:
<%= link_to " exit", destroy_user_session_path, method: :delete %>
After adding the following change to routes.rb it worked,
devise_for :users
devise_scope :user do
get '/users/sign_out' => 'devise/sessions#destroy'
end
Although I don't know the cause, the reason why you are getting that message is because in your routes you have
destroy_member_session DELETE /members/sign_out(.:format) {:action=>"destroy", :controller=>"devise/sessions"}
Which means that route is only available with the DELETE method as opposed to GET. This is a bit weird since in the docs for devise it says that it should create it as GET route (https://github.com/plataformatec/devise/blob/master/lib/devise/rails/routes.rb#L30)
With it as a DELETE route, you should be able to logout using
link_to :logout, destroy_member_session_path, :method => :delete
I just needed to add the
//= require jquery
//= require jquery_ujs
to my application.js
If you want to use :delete method for security reasons and not be dependent on jquery-ujs you can use button_to instead of link_to, like:
button_to "Log out", destroy_user_session_path, method: :delete
if using link_to you must be sure to have javascript active:
Note that if the user has JavaScript disabled, the request will fall
back to using GET.
As seen in docs
In devise.rb, change
config.sign_out_via = :delete
to
config.sign_out_via = :get
This worked for me. I went crazy with this because the default is delete and I don’t understand why.
This works, but I am not sure whether it affects other elements in the application.
We still can use :method => :delete in my code, like that
= link_to "Sign out", destroy_user_session_path,:method => :delete
The reason i think we fail to load javascript that include jquery, make sure
= javascript_include_tag "application" (haml- you can use html too)
to include jquery-ui and jquery-ujs. So if it still error, i suggest to change rails gem in GEMFILE to version 3.2.6 and call bundle update to update gems. It works for me!
= link_to "Sign out", destroy_user_session_path,:method => :delete
will NOT work instead use this,
= link_to "Sign out", destroy_user_session_path,:method => 'delete'
should do the trick or worse case add require jquery_ujs in your application.js
In Rails 6:
I just changed the link_to to button_to, and the 'sign out' works properly
<%= button_to "Sign out", destroy_user_session_path, method: :delete %>
In rails 7, you need to add data: { turbo_method: :delete" } to link_to. So the link_to would look like this
<%= link_to "Log out", destroy_user_session_path, data: { turbo_method: :delete } %>
Using Rails4, I had to use the following method:
<%= link_to "Logout", destroy_admin_session_path, method: :delete %>
Emphasis on where the colons are on method: and :delete
Maybe that will help somebody.
Upgraded from Rails 3.0 to 3.1 and found this problem.
This fixed it for me:
routes.rb:
devise_for: users
devise.rb:
config.sign_out_via = :delete
application.html.erb:
<%= javascript_include_tag "application" %>
* not :defaults
_login_items.html.erb:
<%= link_to('Logout', destroy_user_session_path, :method => :delete) %>
app/assets/javascripts/application.js
//= require jquery
//= require jquery-ui
//= require jquery_ujs
//= require_tree .
and I had in javascript/ jquery.js, jquery_ujs.js from 3.0 version that I've removed.
You may have removed assets/javascripts/*
Run rails generate jquery:install --ui this will generate all the javascripts as shown below
xxxx#xxxxx:~/Projects/Rails_apps/rtest$ rails generate jquery:install --ui
remove public/javascripts/prototype.js
remove public/javascripts/effects.js
remove public/javascripts/dragdrop.js
remove public/javascripts/controls.js
copying jQuery (1.7.1)
create public/javascripts/jquery.js
create public/javascripts/jquery.min.js
copying jQuery UI (1.8.16)
create public/javascripts/jquery-ui.js
create public/javascripts/jquery-ui.min.js
copying jQuery UJS adapter (822920)
remove public/javascripts/rails.js
create public/javascripts/jquery_ujs.js
Go to your layout e.g application.html.erb and edit <%= javascript_include_tag :all %>
That worked for me :)
FWIW I have also run into this problem. Have looked into all of the suggested answers however the only one which worked was to foto open routes.rb and comment out the following line:
devise_for :users
Below that, add the following line:
devise_for :users do get '/users/sign_out' => 'devise/sessions#destroy' end
The problem begins with rails 3.1 in assets/javascript/. Just look for application.js, and if the file doesn't exist, create a file with that name. I don't know why my file disappears or never was created on rails new app... that file is the instance for jquery.
#creamhost say,
devise_for :users do get '/users/sign_out' => 'devise/sessions#destroy' end
but it is not correct solution for me (Rails4). I solved our problem (#Olives' answer),
link_to :logout, destroy_member_session_path, method: :delete
I am using rails version 5. I encounter this problem also. The simple fix I did was to changing the devise configuration in initializes to the default.
From :
config.sign_out_via = :get
To :
config.sign_out_via = :delete
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"
Ref: github.com/heartcombo/devise/issues/4570#issuecomment-740812109
Just use the following for your sign out link:
<%= link_to "Sign out", destroy_user_session_path, method: :delete %>
//= require jquery_ujs
You are missing this line in your assets. There's no need to get /users/signout request. Put this line into JavaScript file at very top of the page.
Had the same problem and remembered it only started happening after I decided to "clean up" my Javascript files. So I ran rails generate jquery:install --ui again and this solved it for me. (You can ignore the --ui part if you don't need JQuery UI, I suppose.)
devise_for :users
devise_scope :user do
get '/users/sign_out' => 'devise/sessions#destroy'
end
That works for me
I believe this error is due to devise library template not aligned with changes on rails 7,
In short, you are not sending the request in method delete as expected due to the Javascript library that does that is now missing.
you can change :
<%= link_to "Sign out", destroy_user_session_path, :method => :delete %>
with
<%= link_to "Sign out", destroy_user_session_path, data: { "turbo-method": :delete }, class: "btn btn-danger ml-3" %>
And it will work again
This worked for me:
<%= link_to 'Sign out', destroy_user_session_path, data: { turbo_method: :delete } %>
It happens only on windows.. Add the following thing to your Application.html.erb file.
devise_for :users
devise_scope :user do
get '/users/sign_out' => 'devise/sessions#destroy'
end