Class: Graphiti::Scope
Instance Attribute Summary collapse
-
#object ⇒ Object
Returns the value of attribute object.
-
#pagination ⇒ Object
readonly
Returns the value of attribute pagination.
-
#unpaginated_object ⇒ Object
Returns the value of attribute unpaginated_object.
Instance Method Summary collapse
- #cache_key ⇒ Object
- #cache_key_with_version ⇒ Object
-
#initialize(object, resource, query, opts = {}) ⇒ Scope
constructor
A new instance of Scope.
- #parent_resource ⇒ Object
- #resolve ⇒ Object
- #resolve_sideloads(results) ⇒ Object
- #updated_at ⇒ Object (also: #last_modified_at)
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
#object ⇒ Object
Returns the value of attribute object.
3 4 5 |
# File 'lib/graphiti/scope.rb', line 3 def object @object end |
#pagination ⇒ Object (readonly)
Returns the value of attribute pagination.
4 5 6 |
# File 'lib/graphiti/scope.rb', line 4 def pagination @pagination end |
#unpaginated_object ⇒ Object
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
#cache_key ⇒ Object
74 75 76 77 78 79 80 81 82 |
# File 'lib/graphiti/scope.rb', line 74 def cache_key # This is the combined cache key for the base query and the query for all sideloads # Changing the query will yield a different cache key cache_keys = sideload_resource_proxies.map { |proxy| proxy.try(:cache_key) } cache_keys << @object.try(:cache_key) # this is what calls into the ORM (ActiveRecord, most likely) ActiveSupport::Cache.(cache_keys.flatten.compact) end |
#cache_key_with_version ⇒ Object
84 85 86 87 88 89 90 91 92 |
# File 'lib/graphiti/scope.rb', line 84 def cache_key_with_version # This is the combined and versioned cache key for the base query and the query for all sideloads # If any returned model's updated_at changes, this key will change cache_keys = sideload_resource_proxies.map { |proxy| proxy.try(:cache_key_with_version) } cache_keys << @object.try(:cache_key_with_version) # this is what calls into ORM (ActiveRecord, most likely) ActiveSupport::Cache.(cache_keys.flatten.compact) end |
#parent_resource ⇒ Object
70 71 72 |
# File 'lib/graphiti/scope.rb', line 70 def parent_resource @resource end |
#resolve ⇒ Object
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 68 |
# 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.config.before_sideload&.call(graphiti_context) 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 |
#updated_at ⇒ Object Also known as: last_modified_at
94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/graphiti/scope.rb', line 94 def updated_at updated_time = nil begin updated_ats = sideload_resource_proxies.map(&:updated_at) updated_ats << @object.maximum(:updated_at) updated_time = updated_ats.compact.max rescue => e Graphiti.log(["error calculating last_modified_at for #{@resource.class}", :red]) Graphiti.log(e) end updated_time || Time.now end |