From d094f513cd673347fe765aa6eb364b675213512e Mon Sep 17 00:00:00 2001 From: Raphael Date: Wed, 24 Jun 2026 12:41:34 +0200 Subject: [PATCH] feat: wip preloading of fields --- app/graphql/types/base_object.rb | 17 ++++++++++++++++- app/graphql/types/namespace_member_type.rb | 4 ++++ app/graphql/types/namespace_type.rb | 2 +- app/graphql/types/user_type.rb | 3 ++- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/app/graphql/types/base_object.rb b/app/graphql/types/base_object.rb index fe4cf814..e9cda43a 100644 --- a/app/graphql/types/base_object.rb +++ b/app/graphql/types/base_object.rb @@ -62,7 +62,20 @@ def self.expose_abilities(abilities, entity_name: graphql_name, subject_resolver define_method(:user_abilities) { object || {} } end - def self.lookahead_field(field, base_scope:, lookaheads: [], conditional_lookaheads: {}) + def self.lookahead_preload(field, preload, profile: nil) + @lookahead_preloads ||= Hash.new { |hash, key| hash[key] = {} } + @lookahead_preloads[profile][field] = preload + end + + def self.lookahead_preloads(profile: nil) + own_preloads = @lookahead_preloads || {} + base_preloads = superclass.respond_to?(:lookahead_preloads) ? superclass.lookahead_preloads : {} + + base_preloads.merge(own_preloads.fetch(nil, {})).merge(own_preloads.fetch(profile, {})) + end + + def self.lookahead_field(field, base_scope:, lookaheads: [], conditional_lookaheads: {}, preload_type: nil, + preload_profile: nil) define_method(field) do |*_args, lookahead:, **_kwargs| field_selected = lambda do |f| lookahead.selects?(f) || @@ -70,6 +83,8 @@ def self.lookahead_field(field, base_scope:, lookaheads: [], conditional_lookahe lookahead.selection(:edges).selection(:node).selects?(f) end + type_lookaheads = preload_type&.lookahead_preloads(profile: preload_profile) || {} + conditional_lookaheads = conditional_lookaheads.merge(type_lookaheads) scope = lookaheads.reduce(base_scope.call(object)) { |acc, f| acc.preload(f) } conditional_lookaheads.reduce(scope) do |acc, (f, preload_field)| diff --git a/app/graphql/types/namespace_member_type.rb b/app/graphql/types/namespace_member_type.rb index fde18f9b..badb4c4e 100644 --- a/app/graphql/types/namespace_member_type.rb +++ b/app/graphql/types/namespace_member_type.rb @@ -12,6 +12,10 @@ class NamespaceMemberType < Types::BaseObject field :member_roles, NamespaceMemberRoleType.connection_type, null: false, description: 'Memberroles of the member' field :roles, NamespaceRoleType.connection_type, null: false, description: 'Roles of the member' + lookahead_preload :namespace, :namespace + lookahead_preload :user, :user + lookahead_preload :namespace, { namespace: :namespace_members }, profile: :namespace_memberships + expose_abilities %i[ assign_member_roles delete_member diff --git a/app/graphql/types/namespace_type.rb b/app/graphql/types/namespace_type.rb index 2d2fbfb1..0d454edf 100644 --- a/app/graphql/types/namespace_type.rb +++ b/app/graphql/types/namespace_type.rb @@ -24,7 +24,7 @@ class NamespaceType < Types::BaseObject field :runtimes, Types::RuntimeType.connection_type, null: false, description: 'Runtime of the namespace' lookahead_field :members, base_scope: ->(object) { object.namespace_members }, - conditional_lookaheads: { user: :user, namespace: :namespace } + preload_type: Types::NamespaceMemberType expose_abilities %i[ invite_member diff --git a/app/graphql/types/user_type.rb b/app/graphql/types/user_type.rb index dce975f2..355b5639 100644 --- a/app/graphql/types/user_type.rb +++ b/app/graphql/types/user_type.rb @@ -48,7 +48,8 @@ class UserType < Types::BaseObject lookahead_field :namespace_memberships, base_scope: ->(object) { object.namespace_memberships }, - conditional_lookaheads: { user: :user, namespace: { namespace: :namespace_members } } + preload_type: Types::NamespaceMemberType, + preload_profile: :namespace_memberships expose_abilities %i[ manage_mfa