diff options
Diffstat (limited to 'app/services/todos/destroy/destroyed_issuable_service.rb')
-rw-r--r-- | app/services/todos/destroy/destroyed_issuable_service.rb | 46 |
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 |