Class: GraphqlLazyLoad::ActiveRecordRelation

Inherits:
Object
  • Object
show all
Defined in:
lib/graphql_lazy_load/active_record_relation.rb

Instance Method Summary collapse

Constructor Details

#initialize(type, association, **params, &block) ⇒ ActiveRecordRelation

Returns a new instance of ActiveRecordRelation.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/graphql_lazy_load/active_record_relation.rb', line 5

def initialize(type, association, **params, &block)
  object_class = type.object.class
  context_key = [type.class, object_class, association]
  @object_id = type.object.id
  @association = association

  # Initialize the loading state for this query,
  # or get the previously-initiated state
  @lazy = type.context[context_key] ||= {
    objects_to_load: Set.new,
    ids: Set.new, # use ids cause cant compare objects
    results: {},
    params: params,
    block: block,
  }
  # Register this to be loaded later unless we've already queued or loaded it
  return if already_loaded_or_queued?
  # use copy of object so it doesnt add preload to associations.
  # this is so associations dont get loaded to object passed so different scopes get reloaded
  lazy_objects.add(
    object_class.column_names.reduce(object_class.new) do |acc, column|
      # only iterate over column in db so if select fields outside usual model
      # values wont throw error
      acc.send("#{column}=", type.object.send(column))
      acc
    end
  )
  lazy_ids.add(object_id)
end

Instance Method Details

#resultObject

Return the loaded record, hitting the database if needed



36
37
38
39
40
41
42
43
44
45
# File 'lib/graphql_lazy_load/active_record_relation.rb', line 36

def result
  if !already_loaded? && any_to_load?
    ActiveRecord::Associations::Preloader.new.preload(lazy_objects.to_a, association, scope)
    lazy_objects.each do |object|
      lazy_results[object.id] = object.send(association)
    end
    lazy_objects.clear
  end
  lazy_results[object_id]
end