Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/preloaders/project_root_ancestor_preloader.rb')
-rw-r--r--app/models/preloaders/project_root_ancestor_preloader.rb37
1 files changed, 37 insertions, 0 deletions
diff --git a/app/models/preloaders/project_root_ancestor_preloader.rb b/app/models/preloaders/project_root_ancestor_preloader.rb
new file mode 100644
index 00000000000..8d04e71774c
--- /dev/null
+++ b/app/models/preloaders/project_root_ancestor_preloader.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+module Preloaders
+ class ProjectRootAncestorPreloader
+ def initialize(projects, namespace_sti_name = :namespace, root_ancestor_preloads = [])
+ @projects = projects
+ @namespace_sti_name = namespace_sti_name
+ @root_ancestor_preloads = root_ancestor_preloads
+ end
+
+ def execute
+ return if @projects.is_a?(ActiveRecord::NullRelation)
+ return unless ::Feature.enabled?(:use_traversal_ids)
+
+ root_query = Namespace.joins("INNER JOIN (#{join_sql}) as root_query ON root_query.root_id = namespaces.id")
+ .select('namespaces.*, root_query.id as source_id')
+
+ root_query = root_query.preload(*@root_ancestor_preloads) if @root_ancestor_preloads.any?
+
+ root_ancestors_by_id = root_query.group_by(&:source_id)
+
+ ActiveRecord::Associations::Preloader.new.preload(@projects, :namespace)
+ @projects.each do |project|
+ project.namespace.root_ancestor = root_ancestors_by_id[project.id]&.first
+ end
+ end
+
+ private
+
+ def join_sql
+ @projects
+ .joins(@namespace_sti_name)
+ .select('projects.id, namespaces.traversal_ids[1] as root_id')
+ .to_sql
+ end
+ end
+end