perf(graphql): improuve dossier loading

This commit is contained in:
Paul Chavard 2022-07-20 21:29:54 +02:00
parent 042703cead
commit 902dc678de
5 changed files with 45 additions and 4 deletions

View file

@ -0,0 +1,23 @@
module Connections
class DossiersConnection < GraphQL::Pagination::ActiveRecordRelationConnection
def initialize(items, lookahead: nil, **kwargs)
super(items, **kwargs)
@lookahead = lookahead
end
def nodes
if @nodes.nil? && preload?
DossierPreloader.new(super).all
else
super
end
end
private
# We check if the query selects champs form dossier. If it's the case we preload the dossier.
def preload?
@lookahead.selection(:nodes).selects?(:champs) || @lookahead.selection(:nodes).selects?(:annotations)
end
end
end

View file

@ -5,7 +5,11 @@ module Types::Champs
field :champs, [Types::ChampType], null: false
def champs
Loaders::Association.for(object.class, :champs).load(object)
if object.champs.loaded?
object.champs
else
Loaders::Association.for(object.class, :champs).load(object)
end
end
end
end

View file

@ -32,7 +32,7 @@ module Types
field :groupe_instructeurs, [Types::GroupeInstructeurType], null: false
field :service, Types::ServiceType, null: true
field :dossiers, Types::DossierType.connection_type, "Liste de tous les dossiers dune démarche.", null: false do
field :dossiers, Types::DossierType.connection_type, "Liste de tous les dossiers dune démarche.", null: false, extras: [:lookahead] do
argument :order, Types::Order, default_value: :asc, required: false, description: "Lordre des dossiers."
argument :created_since, GraphQL::Types::ISO8601DateTime, required: false, description: "Dossiers déposés depuis la date."
argument :updated_since, GraphQL::Types::ISO8601DateTime, required: false, description: "Dossiers mis à jour depuis la date."
@ -72,7 +72,7 @@ module Types
Loaders::Association.for(object.class, :revisions).load(object)
end
def dossiers(updated_since: nil, created_since: nil, state: nil, archived: nil, revision: nil, max_revision: nil, min_revision: nil, order:)
def dossiers(updated_since: nil, created_since: nil, state: nil, archived: nil, revision: nil, max_revision: nil, min_revision: nil, order:, lookahead:)
dossiers = object
.dossiers
.visible_by_administration
@ -108,7 +108,11 @@ module Types
dossiers = dossiers.order_by_created_at(order)
end
dossiers
# We wrap dossiers in a custom connection alongsite the lookahead for the query.
# The custom connection is responsible for preloading paginated dossiers.
# https://graphql-ruby.org/pagination/custom_connections.html#using-a-custom-connection
# https://graphql-ruby.org/queries/lookahead.html
Connections::DossiersConnection.new(dossiers, lookahead: lookahead)
end
def deleted_dossiers(deleted_since: nil, order:)

View file

@ -120,6 +120,8 @@ module Types
Loaders::Champ
.for(object, private: false)
.load(ApplicationRecord.id_from_typed_id(id))
elsif object.champs.loaded?
object.champs
else
Loaders::Association.for(object.class, champs: :type_de_champ).load(object)
end
@ -130,6 +132,8 @@ module Types
Loaders::Champ
.for(object, private: true)
.load(ApplicationRecord.id_from_typed_id(id))
elsif object.champs_private.loaded?
object.champs_private
else
Loaders::Association.for(object.class, champs_private: :type_de_champ).load(object)
end

View file

@ -11,6 +11,12 @@ class DossierPreloader
dossiers
end
def all
dossiers = @dossiers.to_a
load_dossiers(dossiers)
dossiers
end
private
# returns: { revision_id : { type_de_champ_id : position } }