38 lines
1.2 KiB
Ruby
38 lines
1.2 KiB
Ruby
# 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|
|
|
root_ancestor = root_ancestors_by_id[project.id]&.first
|
|
project.namespace.root_ancestor = root_ancestor if root_ancestor.present?
|
|
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
|