Class: Graphiti::Scope

Inherits:
Object show all
Defined in:
lib/graphiti/scope.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(object, resource, query, opts = {}) ⇒ Scope

Returns a new instance of Scope.



5
6
7
8
9
10
11
12
13
14
# File 'lib/graphiti/scope.rb', line 5

def initialize(object, resource, query, opts = {})
  @object = object
  @resource = resource
  @query = query
  @opts = opts

  @object = @resource.around_scoping(@object, @query.hash) { |scope|
    apply_scoping(scope, opts)
  }
end

Instance Attribute Details

#objectObject

Returns the value of attribute object.



3
4
5
# File 'lib/graphiti/scope.rb', line 3

def object
  @object
end

#paginationObject (readonly)

Returns the value of attribute pagination.



4
5
6
# File 'lib/graphiti/scope.rb', line 4

def pagination
  @pagination
end

#unpaginated_objectObject

Returns the value of attribute unpaginated_object.



3
4
5
# File 'lib/graphiti/scope.rb', line 3

def unpaginated_object
  @unpaginated_object
end

Instance Method Details

#resolveObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/graphiti/scope.rb', line 16

def resolve
  if @query.zero_results?
    []
  else
    resolved = broadcast_data { |payload|
      @object = @resource.before_resolve(@object, @query)
      payload[:results] = @resource.resolve(@object)
      payload[:results]
    }
    resolved.compact!
    assign_serializer(resolved)
    yield resolved if block_given?
    @opts[:after_resolve]&.call(resolved)
    resolve_sideloads(resolved) unless @query.sideloads.empty?
    resolved
  end
end

#resolve_sideloads(results) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/graphiti/scope.rb', line 34

def resolve_sideloads(results)
  return if results == []

  concurrent = Graphiti.config.concurrency
  promises = []

  @query.sideloads.each_pair do |name, q|
    sideload = @resource.class.sideload(name)
    next if sideload.nil? || sideload.shared_remote?
    parent_resource = @resource
    graphiti_context = Graphiti.context
    resolve_sideload = -> {
      Graphiti.context = graphiti_context
      sideload.resolve(results, q, parent_resource)
      @resource.adapter.close if concurrent
    }
    if concurrent
      promises << Concurrent::Promise.execute(&resolve_sideload)
    else
      resolve_sideload.call
    end
  end

  if concurrent
    # Wait for all promises to finish
    sleep 0.01 until promises.all? { |p| p.fulfilled? || p.rejected? }
    # Re-raise the error with correct stacktrace
    # OPTION** to avoid failing here?? if so need serializable patch
    # to avoid loading data when association not loaded
    if (rejected = promises.find(&:rejected?))
      raise rejected.reason
    end
  end
end