PERF: delete potentially large associated tables before user_destroyer.destroy transaction

PERF: delete potentially large associated tables before user_destroyer.destroy transaction

diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 8f0afd9..ec9f92f 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -409,6 +409,7 @@ class Admin::UsersController < Admin::AdminController
 
     options = params.slice(:block_email, :block_urls, :block_ip, :context, :delete_as_spammer)
     options[:delete_posts] = ActiveModel::Type::Boolean.new.cast(params[:delete_posts])
+    options[:prepare_for_destroy] = true
 
     hijack do
       begin
diff --git a/app/services/user_destroyer.rb b/app/services/user_destroyer.rb
index 7e2f4ee..b2b19ad 100644
--- a/app/services/user_destroyer.rb
+++ b/app/services/user_destroyer.rb
@@ -21,6 +21,8 @@ class UserDestroyer
     # default to using a transaction
     opts[:transaction] = true if opts[:transaction] != false
 
+    prepare_for_destroy(user) if opts[:prepare_for_destroy] == true
+
     optional_transaction(open_transaction: opts[:transaction]) do
 
       Draft.where(user_id: user.id).delete_all
@@ -111,6 +113,16 @@ class UserDestroyer
 
   protected
 
+  def prepare_for_destroy(user)
+    PostAction.where(user_id: user.id).delete_all
+    UserAction.where('user_id = :user_id OR target_user_id = :user_id OR acting_user_id = :user_id', user_id: user.id).delete_all
+    PostTiming.where(user_id: user.id).delete_all
+    TopicViewItem.where(user_id: user.id).delete_all
+    TopicUser.where(user_id: user.id).delete_all
+    TopicAllowedUser.where(user_id: user.id).delete_all
+    Notification.where(user_id: user.id).delete_all
+  end
+
   def optional_transaction(open_transaction: true)
     if open_transaction
       User.transaction { yield  }
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 414da62..b9251b9 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -3872,7 +3872,7 @@ en:
         cant_delete_all_too_many_posts:
           one: "Can't delete all posts because the user has more than 1 post. (delete_all_posts_max)"
           other: "Can't delete all posts because the user has more than %{count} posts.  (delete_all_posts_max)"
-        delete_confirm: "Are you SURE you want to delete this user? This is permanent!"
+        delete_confirm: "It is generally preferable to anonymize users rather than deleting them, to avoid removing content from existing discussions.<br><br>Are you SURE you want to delete this user? This is permanent!"
         delete_and_block: "Delete and <b>block</b> this email and IP address"
         delete_dont_block: "Delete only"
         deleting_user: "Deleting user..."

GitHub sha: 45f66826

1 Like