I want to allow admins to delete users from a link on the users index.
Desired behavior: When logged in admin clicks "delete" next to a username on the index page, that admin sees a confirmation message. Upon confirming, the user is deleted, admin sees updated index with flash success message.
I've tried two different ways, both failing. All things being equal, I'd prefer to do this using Devise out of the box functionality (e.g. the user_registration_path destroy action, and default flash message).
First way - adding a destroy action to custom user controller:
users/index.html.erb
<% provide(:title, 'All users') %>
<h2>All users</h2>
<%= will_paginate %>
<ul class="users">
<%= render @users %>
</ul>
<%= will_paginate %>
users/_user.html.erb
<li>
<%= gravatar_for user, size: 50 %>
<%= link_to user.name, user %>
<% if current_user.admin? && current_user != user %>
| <%= link_to "delete", user, data: { "turbo-method": :delete,
turbo_confirm: "You sure?" } %>
<% end %>
</li>
users_controller.rb
class UsersController < ApplicationController
before_action :authenticate_user!, :only => [:index, :edit, :update, :destroy]
def show
@user = User.find(params[:id])
end
def index
@users = User.paginate(page: params[:page])
end
def destroy
@user = User.find(params[:id])
@user.destroy
flash[:success] = "User deleted"
redirect_to users_url, status: :see_other
end
end
routes.rb
Rails.application.routes.draw do
devise_for :users, controllers: {
sessions: 'users/sessions',
registrations: 'users/registrations'
}
root "static_pages#home"
get "/about", to: "static_pages#about"
get "/contact", to: "static_pages#contact"
resources :users
end
Using this code, when I click "delete" next to the username, the user show page is loaded with these params:
#<ActionController::Parameters {"controller"=>"users", "action"=>"show", "id"=>"3"} permitted: false>
Second way - using the destroy action in the registrations_controller:
users/_user.html.erb
<li>
<%= gravatar_for user, size: 50 %>
<%= link_to user.name, user %>
<% if current_user.admin? && current_user != user %>
| <%= link_to "delete", user_registration_path, data: { "turbo-method": :delete,
turbo_confirm: "You sure?" } %>
<% end %>
</li>
registrations_controller.rb
# frozen_string_literal: true
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: [:create]
before_action :configure_account_update_params, only: [:update]
before_action :authenticate_user!, :only => [:destroy]
# GET /resource/sign_up
# def new
# super
# end
# POST /resource
# def create
# super
# end
# GET /resource/edit
# def edit
# super
# end
# PUT /resource
# def update
# super
# end
# DELETE /resource
def destroy
super
end
# GET /resource/cancel
# Forces the session data which is usually expired after sign
# in to be expired now. This is useful if the user wants to
# cancel oauth signing in/up in the middle of the process,
# removing all OAuth session data.
# def cancel
# super
# end
# protected
# If you have extra params to permit, append them to the sanitizer.
def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
end
# If you have extra params to permit, append them to the sanitizer.
def configure_account_update_params
devise_parameter_sanitizer.permit(:account_update, keys: [:name])
end
# The path used after sign up.
def after_sign_up_path_for(resource)
super(resource)
user_url(@user)
end
# The path used after sign up for inactive accounts.
# def after_inactive_sign_up_path_for(resource)
# super(resource)
# end
end
Using this code, when I click "delete" next to the username, the users index page is reloaded with params:
#<ActionController::Parameters {"controller"=>"users", "action"=>"index"} permitted: false>