summaryrefslogtreecommitdiff
path: root/app/services/todos/destroy/destroyed_issuable_service.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/todos/destroy/destroyed_issuable_service.rb')
-rw-r--r--app/services/todos/destroy/destroyed_issuable_service.rb46
1 files changed, 46 insertions, 0 deletions
diff --git a/app/services/todos/destroy/destroyed_issuable_service.rb b/app/services/todos/destroy/destroyed_issuable_service.rb
new file mode 100644
index 00000000000..db12965224b
--- /dev/null
+++ b/app/services/todos/destroy/destroyed_issuable_service.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module Todos
+ module Destroy
+ class DestroyedIssuableService
+ BATCH_SIZE = 100
+
+ def initialize(target_id, target_type)
+ @target_id = target_id
+ @target_type = target_type
+ end
+
+ def execute
+ inner_query = Todo.select(:id).for_target(target_id).for_type(target_type).limit(BATCH_SIZE)
+
+ delete_query = <<~SQL
+ DELETE FROM "#{Todo.table_name}"
+ WHERE id IN (#{inner_query.to_sql})
+ RETURNING user_id
+ SQL
+
+ loop do
+ result = ActiveRecord::Base.connection.execute(delete_query)
+
+ break if result.cmd_tuples == 0
+
+ user_ids = result.map { |row| row['user_id'] }.uniq
+
+ invalidate_todos_cache_counts(user_ids)
+ end
+ end
+
+ private
+
+ attr_reader :target_id, :target_type
+
+ def invalidate_todos_cache_counts(user_ids)
+ user_ids.each do |id|
+ # Only build a user instance since we only need its ID for
+ # `User#invalidate_todos_cache_counts` to work.
+ User.new(id: id).invalidate_todos_cache_counts
+ end
+ end
+ end
+ end
+end