Class: Pipeloader::FusionExtension

Inherits:
GraphQL::Schema::FieldExtension
  • Object
show all
Defined in:
lib/pipeloader/field_exact.rb

Overview

The auto-fuse sibling of ProjectionExtension: fuses a plain association field into one ‘WHERE key = ANY($1)` per level (reusing the same sources and safety gates) but selects the WHOLE row and never narrows. Anything that isn’t a fusable association — scalars, custom resolvers, non-AR objects, polymorphic / scoped / non-unique associations, SQLite — just yields and loads normally through the transparent pipelined path. Result is byte-identical, just batched.

Instance Method Summary collapse

Instance Method Details

#resolve(object:, arguments:, context:) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/pipeloader/field_exact.rb', line 125

def resolve(object:, arguments:, context:, **)
  record = object.respond_to?(:object) ? object.object : object
  if record.is_a?(ActiveRecord::Base) &&
     !field.owner.instance_methods(false).include?(field.resolver_method) &&
     (assoc = record.class.reflect_on_association(field.method_str.to_sym))
    if assoc.belongs_to? && Pipeloader.fusable_belongs_to?(assoc)
      fk = record.public_send(assoc.foreign_key)
      return nil if fk.nil?

      return Pipeloader.fuse(context.dataloader, assoc.klass, :by_pk, assoc.klass.primary_key, assoc.klass.column_names.sort, fk)
    elsif assoc.macro == :has_one && Pipeloader.fusable_has_one?(assoc)
      parent_key = record.public_send(assoc.active_record_primary_key)
      return nil if parent_key.nil?

      return Pipeloader.fuse(context.dataloader, assoc.klass, :by_fk_one, assoc.foreign_key, assoc.klass.column_names.sort, parent_key)
    end
  end

  value = yield(object, arguments)
  return value unless value.is_a?(ActiveRecord::Relation)

  proxy = value.respond_to?(:proxy_association) ? value.proxy_association : nil
  if proxy && Pipeloader.fusable_has_many?(proxy.reflection, value)
    refl = proxy.reflection
    parent_key = proxy.owner.public_send(refl.active_record_primary_key)
    return Pipeloader.fuse(context.dataloader, refl.klass, :by_fk_many, refl.foreign_key, refl.klass.column_names.sort, parent_key)
  end

  value # bare relation/record -> loads whole-row through the transparent path
end