diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 0b54b14..cb9b88d 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -1,7 +1,8 @@
class UsersController < ApplicationController
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 :admin_user, only: [ :destroy ]
def index
# @users = User.all
@@ -46,6 +47,12 @@ class UsersController < ApplicationController
end
end
+ def destroy
+ User.find(params[:id]).destroy
+ flash[:success] = "User deleted"
+ redirect_to users_url
+ end
+
private
def user_params
@@ -65,4 +72,8 @@ class UsersController < ApplicationController
@user = User.find(params[:id])
redirect_to(root_url) unless current_user?(@user)
end
+
+ def admin_user
+ redirect_to(root_url) unless current_user.admin?
+ end
end
diff --git a/app/views/users/_user.html.erb b/app/views/users/_user.html.erb
index d54c0e3..be73320 100644
--- a/app/views/users/_user.html.erb
+++ b/app/views/users/_user.html.erb
@@ -1,4 +1,11 @@
<%= 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,
+ confirm: "You sure?"
+ } %>
+ <% end %>
\ No newline at end of file
diff --git a/db/migrate/20250105095157_add_admin_to_users.rb b/db/migrate/20250105095157_add_admin_to_users.rb
new file mode 100644
index 0000000..c1f08cf
--- /dev/null
+++ b/db/migrate/20250105095157_add_admin_to_users.rb
@@ -0,0 +1,5 @@
+class AddAdminToUsers < ActiveRecord::Migration[8.0]
+ def change
+ add_column :users, :admin, :boolean, default: false
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index ee50448..93b2f85 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# 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|
t.string "name"
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.string "password_digest"
t.string "remember_digest"
+ t.boolean "admin", default: false
t.index ["email"], name: "index_users_on_email", unique: true
end
end
diff --git a/db/seeds.rb b/db/seeds.rb
index 155583d..4c18990 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -11,7 +11,8 @@
User.create!(name: "Example User",
email: "example@example.com",
password: "foobar",
- password_confirmation: "foobar")
+ password_confirmation: "foobar",
+ admin: true)
99.times do |n|
name = Faker::Name.name
diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb
index 9aca241..14fba91 100644
--- a/test/controllers/users_controller_test.rb
+++ b/test/controllers/users_controller_test.rb
@@ -35,4 +35,30 @@ class UsersControllerTest < ActionDispatch::IntegrationTest
assert flash.empty?
assert_redirected_to root_url
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
diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml
index 2f60abe..7944493 100644
--- a/test/fixtures/users.yml
+++ b/test/fixtures/users.yml
@@ -7,6 +7,7 @@ one:
michael:
name: Michael Example
email: michael@example.com
+ admin: true
password_digest: <%= User.digest('password') %>
archer:
diff --git a/test/integration/users_index_test.rb b/test/integration/users_index_test.rb
index a2064d1..5b11830 100644
--- a/test/integration/users_index_test.rb
+++ b/test/integration/users_index_test.rb
@@ -2,16 +2,26 @@ require "test_helper"
class UsersIndexTest < ActionDispatch::IntegrationTest
def setup
- @user = users(:michael)
+ @admin = users(:michael)
+ @non_admin = users(:archer)
end
- test "index including pagination" do
- log_in_as(@user)
+ test "index including pagination and delete links" do
+ log_in_as(@admin)
get users_path
assert_template "users/index"
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
+ 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