blob: 0d256579fe04d7e2396c890e74cf155eed90b857 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
# frozen_string_literal: true
module Topics
class MergeService
attr_accessor :source_topic, :target_topic
def initialize(source_topic, target_topic)
@source_topic = source_topic
@target_topic = target_topic
end
def execute
validate_parameters!
::Projects::ProjectTopic.transaction do
move_project_topics
refresh_target_topic_counters
delete_source_topic
end
end
private
def validate_parameters!
raise ArgumentError, 'The source topic is not a topic.' unless source_topic.is_a?(Projects::Topic)
raise ArgumentError, 'The target topic is not a topic.' unless target_topic.is_a?(Projects::Topic)
raise ArgumentError, 'The source topic and the target topic are identical.' if source_topic == target_topic
end
# rubocop: disable CodeReuse/ActiveRecord
def move_project_topics
project_ids_for_projects_currently_using_source_and_target = ::Projects::ProjectTopic
.where(topic_id: target_topic).select(:project_id)
# Only update for projects that exclusively use the source topic
::Projects::ProjectTopic.where(topic_id: source_topic.id)
.where.not(project_id: project_ids_for_projects_currently_using_source_and_target)
.update_all(topic_id: target_topic.id)
# Delete source topic for projects that were using source and target
::Projects::ProjectTopic.where(topic_id: source_topic.id).delete_all
end
def refresh_target_topic_counters
target_topic.update!(
total_projects_count: total_projects_count(target_topic.id),
non_private_projects_count: non_private_projects_count(target_topic.id)
)
end
def delete_source_topic
source_topic.destroy!
end
def total_projects_count(topic_id)
::Projects::ProjectTopic.where(topic_id: topic_id).count
end
def non_private_projects_count(topic_id)
::Projects::ProjectTopic.joins(:project).where(topic_id: topic_id).where('projects.visibility_level in (10, 20)')
.count
end
# rubocop: enable CodeReuse/ActiveRecord
end
end
|