debian-mirror-gitlab/lib/gitlab/graphql/loaders/lazy_relation_loader.rb
2023-06-20 00:43:36 +05:30

74 lines
1.9 KiB
Ruby

# frozen_string_literal: true
module Gitlab
module Graphql
module Loaders
class LazyRelationLoader
class << self
attr_accessor :model, :association
# Automatically register the inheriting
# classes to GitlabSchema as lazy objects.
def inherited(klass)
GitlabSchema.lazy_resolve(klass, :load)
end
end
def initialize(query_ctx, object, **kwargs)
@query_ctx = query_ctx
@object = object
@kwargs = kwargs
query_ctx[loader_cache_key] ||= Registry.new(relation(**kwargs))
query_ctx[loader_cache_key].register(object)
end
# Returns an instance of `RelationProxy` for the object (parent model).
# The returned object behaves like an Active Record relation to support
# keyset pagination.
def load
case reflection.macro
when :has_many
relation_proxy
when :has_one
relation_proxy.last
else
raise 'Not supported association type!'
end
end
private
attr_reader :query_ctx, :object, :kwargs
delegate :model, :association, to: :"self.class"
# Implement this one if you want to filter the relation
def relation(**)
base_relation
end
def loader_cache_key
@loader_cache_key ||= self.class.name.to_s + kwargs.sort.to_s
end
def base_relation
placeholder_record.association(association).scope
end
# This will only work for HasMany and HasOne associations for now
def placeholder_record
model.new(reflection.active_record_primary_key => 0)
end
def reflection
model.reflections[association.to_s]
end
def relation_proxy
RelationProxy.new(object, query_ctx[loader_cache_key])
end
end
end
end
end