feat: add user deletion functionality
- Implement user destroy action in UsersController - Add admin check for user deletion - Update user view to include delete link for admins - Add migration to add admin attribute to users - Update tests to cover new admin functionality This commit introduces the ability for admin users to delete other users from the system. It includes necessary checks to ensure that only admins can perform this action, along with updates to the user interface and tests to validate the new behavior.
This commit is contained in:
parent
022eae3029
commit
f2c7d02eed
@ -1,7 +1,8 @@
|
|||||||
class UsersController < ApplicationController
|
class UsersController < ApplicationController
|
||||||
include SessionsHelper
|
include SessionsHelper
|
||||||
before_action :logged_in_user, only: [ :index, :edit, :update ]
|
before_action :logged_in_user, only: [ :index, :edit, :update, :destroy ]
|
||||||
before_action :correct_user, only: [ :edit, :update ]
|
before_action :correct_user, only: [ :edit, :update ]
|
||||||
|
before_action :admin_user, only: [ :destroy ]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
# @users = User.all
|
# @users = User.all
|
||||||
@ -46,6 +47,12 @@ class UsersController < ApplicationController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
User.find(params[:id]).destroy
|
||||||
|
flash[:success] = "User deleted"
|
||||||
|
redirect_to users_url
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def user_params
|
def user_params
|
||||||
@ -65,4 +72,8 @@ class UsersController < ApplicationController
|
|||||||
@user = User.find(params[:id])
|
@user = User.find(params[:id])
|
||||||
redirect_to(root_url) unless current_user?(@user)
|
redirect_to(root_url) unless current_user?(@user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def admin_user
|
||||||
|
redirect_to(root_url) unless current_user.admin?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
<li>
|
<li>
|
||||||
<%= gravatar_for user, size: 50 %>
|
<%= gravatar_for user, size: 50 %>
|
||||||
<%= link_to user.name, user %>
|
<%= link_to user.name, user %>
|
||||||
|
<% if current_user.admin? && !current_user?(user) %>
|
||||||
|
| <%= link_to "delete", user,
|
||||||
|
data: {
|
||||||
|
turbo_method: :delete,
|
||||||
|
confirm: "You sure?"
|
||||||
|
} %>
|
||||||
|
<% end %>
|
||||||
</li>
|
</li>
|
5
db/migrate/20250105095157_add_admin_to_users.rb
Normal file
5
db/migrate/20250105095157_add_admin_to_users.rb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
class AddAdminToUsers < ActiveRecord::Migration[8.0]
|
||||||
|
def change
|
||||||
|
add_column :users, :admin, :boolean, default: false
|
||||||
|
end
|
||||||
|
end
|
3
db/schema.rb
generated
3
db/schema.rb
generated
@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[8.0].define(version: 2025_01_02_072521) do
|
ActiveRecord::Schema[8.0].define(version: 2025_01_05_095157) do
|
||||||
create_table "users", force: :cascade do |t|
|
create_table "users", force: :cascade do |t|
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.string "email"
|
t.string "email"
|
||||||
@ -18,6 +18,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_01_02_072521) do
|
|||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.string "password_digest"
|
t.string "password_digest"
|
||||||
t.string "remember_digest"
|
t.string "remember_digest"
|
||||||
|
t.boolean "admin", default: false
|
||||||
t.index ["email"], name: "index_users_on_email", unique: true
|
t.index ["email"], name: "index_users_on_email", unique: true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
User.create!(name: "Example User",
|
User.create!(name: "Example User",
|
||||||
email: "example@example.com",
|
email: "example@example.com",
|
||||||
password: "foobar",
|
password: "foobar",
|
||||||
password_confirmation: "foobar")
|
password_confirmation: "foobar",
|
||||||
|
admin: true)
|
||||||
|
|
||||||
99.times do |n|
|
99.times do |n|
|
||||||
name = Faker::Name.name
|
name = Faker::Name.name
|
||||||
|
@ -35,4 +35,30 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
|
|||||||
assert flash.empty?
|
assert flash.empty?
|
||||||
assert_redirected_to root_url
|
assert_redirected_to root_url
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "should not allow the admin attribute to be edited via the web" do
|
||||||
|
log_in_as(@other_user)
|
||||||
|
assert_not @other_user.admin?
|
||||||
|
patch user_path(@other_user), params: {
|
||||||
|
user: { password: "password",
|
||||||
|
password_confirmation: "password",
|
||||||
|
admin: true }
|
||||||
|
}
|
||||||
|
assert_not @other_user.reload.admin?
|
||||||
|
end
|
||||||
|
|
||||||
|
test "should redirect destroy when not logged in" do
|
||||||
|
assert_no_difference "User.count" do
|
||||||
|
delete user_path(@user)
|
||||||
|
end
|
||||||
|
assert_redirected_to login_url
|
||||||
|
end
|
||||||
|
|
||||||
|
test "should redirect destroy when logged in as a non-admin" do
|
||||||
|
log_in_as(@other_user)
|
||||||
|
assert_no_difference "User.count" do
|
||||||
|
delete user_path(@user)
|
||||||
|
end
|
||||||
|
assert_redirected_to root_url
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
1
test/fixtures/users.yml
vendored
1
test/fixtures/users.yml
vendored
@ -7,6 +7,7 @@ one:
|
|||||||
michael:
|
michael:
|
||||||
name: Michael Example
|
name: Michael Example
|
||||||
email: michael@example.com
|
email: michael@example.com
|
||||||
|
admin: true
|
||||||
password_digest: <%= User.digest('password') %>
|
password_digest: <%= User.digest('password') %>
|
||||||
|
|
||||||
archer:
|
archer:
|
||||||
|
@ -2,16 +2,26 @@ require "test_helper"
|
|||||||
|
|
||||||
class UsersIndexTest < ActionDispatch::IntegrationTest
|
class UsersIndexTest < ActionDispatch::IntegrationTest
|
||||||
def setup
|
def setup
|
||||||
@user = users(:michael)
|
@admin = users(:michael)
|
||||||
|
@non_admin = users(:archer)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "index including pagination" do
|
test "index including pagination and delete links" do
|
||||||
log_in_as(@user)
|
log_in_as(@admin)
|
||||||
get users_path
|
get users_path
|
||||||
assert_template "users/index"
|
assert_template "users/index"
|
||||||
assert_select "ul.pagination"
|
assert_select "ul.pagination"
|
||||||
User.page(1).each do |user|
|
|
||||||
|
first_page_of_users = User.page(1)
|
||||||
|
first_page_of_users.each do |user|
|
||||||
assert_select "a[href=?]", user_path(user), text: user.name
|
assert_select "a[href=?]", user_path(user), text: user.name
|
||||||
|
unless user == @admin
|
||||||
|
assert_select "a[href=?]", user_path(user), text: "delete"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_difference "User.count", -1 do
|
||||||
|
delete user_path(@non_admin)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user