graphiti-activegraph 1.3.1 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/specs.yml +58 -59
- data/.gitignore +59 -59
- data/.hound.yml +4 -0
- data/.rspec +1 -1
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +58 -54
- data/CHANGELOG_PRE_1.0.0.md +70 -70
- data/Gemfile +3 -3
- data/LICENSE.txt +21 -21
- data/README.md +130 -130
- data/docs/deserializer.md +40 -40
- data/graphiti-activegraph.gemspec +34 -34
- data/lib/graphiti/active_graph/adapters/active_graph/function_sideload.rb +7 -7
- data/lib/graphiti/active_graph/adapters/active_graph/has_many_sideload.rb +7 -7
- data/lib/graphiti/active_graph/adapters/active_graph/has_one_sideload.rb +7 -7
- data/lib/graphiti/active_graph/adapters/active_graph/polymorphic_belongs_to.rb +11 -11
- data/lib/graphiti/active_graph/adapters/active_graph/sideload.rb +26 -26
- data/lib/graphiti/active_graph/adapters/active_graph.rb +183 -183
- data/lib/graphiti/active_graph/concerns/path_relationships.rb +44 -44
- data/lib/graphiti/active_graph/concerns/relationships.rb +15 -15
- data/lib/graphiti/active_graph/deserializer.rb +138 -138
- data/lib/graphiti/active_graph/extensions/context.rb +17 -17
- data/lib/graphiti/active_graph/extensions/grouping/params.rb +101 -52
- data/lib/graphiti/active_graph/extensions/query_dsl/performer.rb +38 -38
- data/lib/graphiti/active_graph/extensions/query_dsl/query_generator.rb +20 -20
- data/lib/graphiti/active_graph/extensions/query_params.rb +27 -27
- data/lib/graphiti/active_graph/extensions/resources/authorizationable.rb +29 -29
- data/lib/graphiti/active_graph/extensions/resources/payload_combinable.rb +24 -24
- data/lib/graphiti/active_graph/extensions/resources/preloadable.rb +19 -19
- data/lib/graphiti/active_graph/extensions/resources/rel.rb +19 -19
- data/lib/graphiti/active_graph/jsonapi_ext/include_directive.rb +66 -66
- data/lib/graphiti/active_graph/jsonapi_ext/serializable/resource_ext.rb +8 -8
- data/lib/graphiti/active_graph/query.rb +76 -76
- data/lib/graphiti/active_graph/request_validators/validator.rb +9 -9
- data/lib/graphiti/active_graph/resource.rb +103 -103
- data/lib/graphiti/active_graph/resource_proxy.rb +86 -86
- data/lib/graphiti/active_graph/resources/interface.rb +14 -14
- data/lib/graphiti/active_graph/resources/persistence.rb +25 -25
- data/lib/graphiti/active_graph/runner.rb +39 -39
- data/lib/graphiti/active_graph/scope.rb +28 -28
- data/lib/graphiti/active_graph/scoping/association_eager_load.rb +34 -34
- data/lib/graphiti/active_graph/scoping/filter.rb +49 -49
- data/lib/graphiti/active_graph/scoping/filterable.rb +12 -12
- data/lib/graphiti/active_graph/scoping/include.rb +48 -48
- data/lib/graphiti/active_graph/scoping/internal/extra_field_normalizer.rb +76 -76
- data/lib/graphiti/active_graph/scoping/internal/include_normalizer.rb +82 -82
- data/lib/graphiti/active_graph/scoping/internal/path_descriptor.rb +94 -94
- data/lib/graphiti/active_graph/scoping/internal/sort_normalizer.rb +54 -54
- data/lib/graphiti/active_graph/scoping/internal/sorting_aliases.rb +35 -35
- data/lib/graphiti/active_graph/scoping/internal/sparse_fields_eagerloading.rb +28 -28
- data/lib/graphiti/active_graph/serializer.rb +15 -15
- data/lib/graphiti/active_graph/sideload_resolve.rb +119 -119
- data/lib/graphiti/active_graph/util/parsers/rel_chain.rb +27 -27
- data/lib/graphiti/active_graph/util/relationship_payload.rb +33 -33
- data/lib/graphiti/active_graph/util/serializer_attribute.rb +17 -17
- data/lib/graphiti/active_graph/util/serializer_relationship.rb +28 -28
- data/lib/graphiti/active_graph/util/transformers/relation_param.rb +56 -56
- data/lib/graphiti/active_graph/version.rb +5 -5
- data/lib/graphiti/sidepost_configuration.rb +9 -9
- data/lib/graphiti-activegraph.rb +43 -43
- metadata +5 -3
|
@@ -1,119 +1,119 @@
|
|
|
1
|
-
module Graphiti::ActiveGraph
|
|
2
|
-
module SideloadResolve
|
|
3
|
-
PRELOAD_METHOD_PREFIX = 'preload_'.freeze
|
|
4
|
-
|
|
5
|
-
def initialize(object, resource, query, opts = {})
|
|
6
|
-
@object = object
|
|
7
|
-
@resource = resource
|
|
8
|
-
@query = query
|
|
9
|
-
@opts = opts
|
|
10
|
-
@unpaginated_object = opts[:unpaginated_query].presence || @object
|
|
11
|
-
|
|
12
|
-
return if opts[:preloaded]
|
|
13
|
-
@object = @resource.around_scoping(@object, @query.hash) { |scope|
|
|
14
|
-
apply_scoping(scope, opts)
|
|
15
|
-
}
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def resolve_sideloads(parents)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def resolve
|
|
22
|
-
resolve_with_callbacks.tap { |results| preload_extra_fields(results) }
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
private
|
|
26
|
-
|
|
27
|
-
def resolve_with_callbacks
|
|
28
|
-
if @query.zero_results?
|
|
29
|
-
[]
|
|
30
|
-
else
|
|
31
|
-
resolved = broadcast_data { |payload|
|
|
32
|
-
@object = @resource.before_resolve(@object, @query)
|
|
33
|
-
payload[:results] = @resource.resolve(@object)
|
|
34
|
-
payload[:results]
|
|
35
|
-
}
|
|
36
|
-
resolved.compact!
|
|
37
|
-
assign_serializer(resolved)
|
|
38
|
-
yield resolved if block_given?
|
|
39
|
-
@opts[:after_resolve]&.call(resolved)
|
|
40
|
-
resolve_sideloads(resolved) unless @query.sideloads.empty?
|
|
41
|
-
resolved
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def preload_extra_fields(results)
|
|
46
|
-
@query.extra_fields.each do |type, extra_field_names|
|
|
47
|
-
extra_field_names.each do |name|
|
|
48
|
-
next unless preload_extra_field?(type, name)
|
|
49
|
-
|
|
50
|
-
records_for_preload = collect_records_for_preload(type, results)
|
|
51
|
-
result_map = fetch_preloaded_data(type, name, records_for_preload)
|
|
52
|
-
assign_preloaded_data(records_for_preload, name, result_map)
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def fetch_preloaded_data(type, extra_field_name, results)
|
|
58
|
-
resource_for_preload(type).model.public_send(default_preload_method(extra_field_name), results.pluck(:id).uniq)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def assign_preloaded_data(results, extra_field_name, result_map)
|
|
62
|
-
results.each { |r| r.public_send("#{extra_field_name}=", result_map[r.id]) }
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def preload_extra_field?(type, extra_field_name)
|
|
66
|
-
resource = resource_for_preload(type)
|
|
67
|
-
resource && resource.extra_attribute?(extra_field_name) && resource.model.respond_to?(default_preload_method(extra_field_name))
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def resource_for_preload(type)
|
|
71
|
-
return @resource if type == @resource.type
|
|
72
|
-
|
|
73
|
-
find_resource_in_included_associations(type) unless @query.sideloads.empty?
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def find_resource_in_included_associations(type, sideload_query = @query)
|
|
77
|
-
sideload_query.sideloads.values.each do |sideload|
|
|
78
|
-
return sideload.resource if sideload.resource.type == type
|
|
79
|
-
|
|
80
|
-
resource = find_resource_in_included_associations(type, sideload)
|
|
81
|
-
return resource if resource
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
nil
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def default_preload_method(extra_field_name)
|
|
88
|
-
"#{PRELOAD_METHOD_PREFIX}#{extra_field_name}"
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def collect_records_for_preload(type, results)
|
|
92
|
-
base_records = resource_matches_type?(@resource, type) ? Array(results) : []
|
|
93
|
-
sideloaded_records = collect_sideloaded_records(Array(results), @query, type)
|
|
94
|
-
(base_records + sideloaded_records).flatten.compact.uniq
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def collect_sideloaded_records(source_records, sideload_query, type)
|
|
98
|
-
return [] if source_records.empty? || sideload_query.sideloads.empty?
|
|
99
|
-
|
|
100
|
-
sideload_query.sideloads.flat_map do |sideload_name, nested_query|
|
|
101
|
-
associated_records = collect_associated_records(source_records, sideload_name)
|
|
102
|
-
matched_records = resource_matches_type?(nested_query.resource, type) ? associated_records : []
|
|
103
|
-
matched_records + collect_sideloaded_records(associated_records, nested_query, type)
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def resource_matches_type?(resource, type)
|
|
108
|
-
resource&.type == type
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def collect_associated_records(source_records, sideload_name)
|
|
112
|
-
source_records.flat_map do |parent|
|
|
113
|
-
next [] unless parent.respond_to?(sideload_name)
|
|
114
|
-
|
|
115
|
-
Array(parent.public_send(sideload_name)).compact
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
end
|
|
1
|
+
module Graphiti::ActiveGraph
|
|
2
|
+
module SideloadResolve
|
|
3
|
+
PRELOAD_METHOD_PREFIX = 'preload_'.freeze
|
|
4
|
+
|
|
5
|
+
def initialize(object, resource, query, opts = {})
|
|
6
|
+
@object = object
|
|
7
|
+
@resource = resource
|
|
8
|
+
@query = query
|
|
9
|
+
@opts = opts
|
|
10
|
+
@unpaginated_object = opts[:unpaginated_query].presence || @object
|
|
11
|
+
|
|
12
|
+
return if opts[:preloaded]
|
|
13
|
+
@object = @resource.around_scoping(@object, @query.hash) { |scope|
|
|
14
|
+
apply_scoping(scope, opts)
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def resolve_sideloads(parents)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def resolve
|
|
22
|
+
resolve_with_callbacks.tap { |results| preload_extra_fields(results) }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def resolve_with_callbacks
|
|
28
|
+
if @query.zero_results?
|
|
29
|
+
[]
|
|
30
|
+
else
|
|
31
|
+
resolved = broadcast_data { |payload|
|
|
32
|
+
@object = @resource.before_resolve(@object, @query)
|
|
33
|
+
payload[:results] = @resource.resolve(@object)
|
|
34
|
+
payload[:results]
|
|
35
|
+
}
|
|
36
|
+
resolved.compact!
|
|
37
|
+
assign_serializer(resolved)
|
|
38
|
+
yield resolved if block_given?
|
|
39
|
+
@opts[:after_resolve]&.call(resolved)
|
|
40
|
+
resolve_sideloads(resolved) unless @query.sideloads.empty?
|
|
41
|
+
resolved
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def preload_extra_fields(results)
|
|
46
|
+
@query.extra_fields.each do |type, extra_field_names|
|
|
47
|
+
extra_field_names.each do |name|
|
|
48
|
+
next unless preload_extra_field?(type, name)
|
|
49
|
+
|
|
50
|
+
records_for_preload = collect_records_for_preload(type, results)
|
|
51
|
+
result_map = fetch_preloaded_data(type, name, records_for_preload)
|
|
52
|
+
assign_preloaded_data(records_for_preload, name, result_map)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def fetch_preloaded_data(type, extra_field_name, results)
|
|
58
|
+
resource_for_preload(type).model.public_send(default_preload_method(extra_field_name), results.pluck(:id).uniq)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def assign_preloaded_data(results, extra_field_name, result_map)
|
|
62
|
+
results.each { |r| r.public_send("#{extra_field_name}=", result_map[r.id]) }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def preload_extra_field?(type, extra_field_name)
|
|
66
|
+
resource = resource_for_preload(type)
|
|
67
|
+
resource && resource.extra_attribute?(extra_field_name) && resource.model.respond_to?(default_preload_method(extra_field_name))
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def resource_for_preload(type)
|
|
71
|
+
return @resource if type == @resource.type
|
|
72
|
+
|
|
73
|
+
find_resource_in_included_associations(type) unless @query.sideloads.empty?
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def find_resource_in_included_associations(type, sideload_query = @query)
|
|
77
|
+
sideload_query.sideloads.values.each do |sideload|
|
|
78
|
+
return sideload.resource if sideload.resource.type == type
|
|
79
|
+
|
|
80
|
+
resource = find_resource_in_included_associations(type, sideload)
|
|
81
|
+
return resource if resource
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
nil
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def default_preload_method(extra_field_name)
|
|
88
|
+
"#{PRELOAD_METHOD_PREFIX}#{extra_field_name}"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def collect_records_for_preload(type, results)
|
|
92
|
+
base_records = resource_matches_type?(@resource, type) ? Array(results) : []
|
|
93
|
+
sideloaded_records = collect_sideloaded_records(Array(results), @query, type)
|
|
94
|
+
(base_records + sideloaded_records).flatten.compact.uniq
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def collect_sideloaded_records(source_records, sideload_query, type)
|
|
98
|
+
return [] if source_records.empty? || sideload_query.sideloads.empty?
|
|
99
|
+
|
|
100
|
+
sideload_query.sideloads.flat_map do |sideload_name, nested_query|
|
|
101
|
+
associated_records = collect_associated_records(source_records, sideload_name)
|
|
102
|
+
matched_records = resource_matches_type?(nested_query.resource, type) ? associated_records : []
|
|
103
|
+
matched_records + collect_sideloaded_records(associated_records, nested_query, type)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def resource_matches_type?(resource, type)
|
|
108
|
+
resource&.type == type
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def collect_associated_records(source_records, sideload_name)
|
|
112
|
+
source_records.flat_map do |parent|
|
|
113
|
+
next [] unless parent.respond_to?(sideload_name)
|
|
114
|
+
|
|
115
|
+
Array(parent.public_send(sideload_name)).compact
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
module Graphiti::ActiveGraph
|
|
2
|
-
module Util
|
|
3
|
-
module Parsers
|
|
4
|
-
class RelChain < Parslet::Parser
|
|
5
|
-
VAR_CHAR = 'a-z_'
|
|
6
|
-
|
|
7
|
-
rule(:asterisk) { str('*') }
|
|
8
|
-
rule(:range) { str('..') }
|
|
9
|
-
rule(:dot) { str('.') }
|
|
10
|
-
rule(:none) { str('') }
|
|
11
|
-
rule(:number) { match('[\d]').repeat(1) }
|
|
12
|
-
rule(:number?) { number | none }
|
|
13
|
-
rule(:identifier) { match("[#{VAR_CHAR}]") >> match("[#{VAR_CHAR}0-9]").repeat(0) }
|
|
14
|
-
rule(:identifier?) { identifier | none }
|
|
15
|
-
rule(:rel_name) { identifier?.as(:rel_name) }
|
|
16
|
-
rule(:length) { asterisk.as(:ast) >> number?.maybe.as(:min) >> range.as(:range).maybe >> number?.maybe.as(:max) }
|
|
17
|
-
rule(:rel) { rel_name >> length.maybe }
|
|
18
|
-
|
|
19
|
-
rule(:rel_chain) { rel >> (dot >> rel).repeat(0) }
|
|
20
|
-
root(:rel_chain)
|
|
21
|
-
|
|
22
|
-
rule(:limit) { number?.as(:limit_digit) >> asterisk.as(:limit_ast) }
|
|
23
|
-
rule(:rel_param_rule) { limit.maybe.as(:limit_part) >> rel_name >> length.maybe.as(:length_part) }
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
1
|
+
module Graphiti::ActiveGraph
|
|
2
|
+
module Util
|
|
3
|
+
module Parsers
|
|
4
|
+
class RelChain < Parslet::Parser
|
|
5
|
+
VAR_CHAR = 'a-z_'
|
|
6
|
+
|
|
7
|
+
rule(:asterisk) { str('*') }
|
|
8
|
+
rule(:range) { str('..') }
|
|
9
|
+
rule(:dot) { str('.') }
|
|
10
|
+
rule(:none) { str('') }
|
|
11
|
+
rule(:number) { match('[\d]').repeat(1) }
|
|
12
|
+
rule(:number?) { number | none }
|
|
13
|
+
rule(:identifier) { match("[#{VAR_CHAR}]") >> match("[#{VAR_CHAR}0-9]").repeat(0) }
|
|
14
|
+
rule(:identifier?) { identifier | none }
|
|
15
|
+
rule(:rel_name) { identifier?.as(:rel_name) }
|
|
16
|
+
rule(:length) { asterisk.as(:ast) >> number?.maybe.as(:min) >> range.as(:range).maybe >> number?.maybe.as(:max) }
|
|
17
|
+
rule(:rel) { rel_name >> length.maybe }
|
|
18
|
+
|
|
19
|
+
rule(:rel_chain) { rel >> (dot >> rel).repeat(0) }
|
|
20
|
+
root(:rel_chain)
|
|
21
|
+
|
|
22
|
+
rule(:limit) { number?.as(:limit_digit) >> asterisk.as(:limit_ast) }
|
|
23
|
+
rule(:rel_param_rule) { limit.maybe.as(:limit_part) >> rel_name >> length.maybe.as(:length_part) }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
module Graphiti::ActiveGraph
|
|
2
|
-
module Util
|
|
3
|
-
module RelationshipPayload
|
|
4
|
-
def payload_for(sideload, relationship_payload)
|
|
5
|
-
type = relationship_payload[:meta][:jsonapi_type]&.to_sym
|
|
6
|
-
|
|
7
|
-
# For polymorphic *sideloads*, grab the correct child sideload
|
|
8
|
-
if sideload.resource.type != type && sideload.type == :polymorphic_belongs_to
|
|
9
|
-
sideload = sideload.child_for_type!(type)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
# For polymorphic *resources*, grab the correct child resource
|
|
13
|
-
resource = sideload.resource
|
|
14
|
-
if resource.type != type && resource.polymorphic?
|
|
15
|
-
resource = resource.class.resource_for_type(type).new
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
relationship_payload[:meta][:method] ||= :update
|
|
19
|
-
|
|
20
|
-
{
|
|
21
|
-
resource: resource,
|
|
22
|
-
sideload: sideload,
|
|
23
|
-
is_polymorphic: sideload.polymorphic_child?,
|
|
24
|
-
primary_key: sideload.primary_key,
|
|
25
|
-
foreign_key: sideload.foreign_key,
|
|
26
|
-
attributes: relationship_payload[:attributes],
|
|
27
|
-
meta: relationship_payload[:meta],
|
|
28
|
-
relationships: relationship_payload[:relationships]
|
|
29
|
-
}
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
1
|
+
module Graphiti::ActiveGraph
|
|
2
|
+
module Util
|
|
3
|
+
module RelationshipPayload
|
|
4
|
+
def payload_for(sideload, relationship_payload)
|
|
5
|
+
type = relationship_payload[:meta][:jsonapi_type]&.to_sym
|
|
6
|
+
|
|
7
|
+
# For polymorphic *sideloads*, grab the correct child sideload
|
|
8
|
+
if sideload.resource.type != type && sideload.type == :polymorphic_belongs_to
|
|
9
|
+
sideload = sideload.child_for_type!(type)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# For polymorphic *resources*, grab the correct child resource
|
|
13
|
+
resource = sideload.resource
|
|
14
|
+
if resource.type != type && resource.polymorphic?
|
|
15
|
+
resource = resource.class.resource_for_type(type).new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
relationship_payload[:meta][:method] ||= :update
|
|
19
|
+
|
|
20
|
+
{
|
|
21
|
+
resource: resource,
|
|
22
|
+
sideload: sideload,
|
|
23
|
+
is_polymorphic: sideload.polymorphic_child?,
|
|
24
|
+
primary_key: sideload.primary_key,
|
|
25
|
+
foreign_key: sideload.foreign_key,
|
|
26
|
+
attributes: relationship_payload[:attributes],
|
|
27
|
+
meta: relationship_payload[:meta],
|
|
28
|
+
relationships: relationship_payload[:relationships]
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
module Graphiti::ActiveGraph
|
|
2
|
-
module Util
|
|
3
|
-
module SerializerAttribute
|
|
4
|
-
def wrap_proc(inner)
|
|
5
|
-
typecast_ref = typecast(Graphiti::Types[@attr[:type]][:read])
|
|
6
|
-
->(serializer_instance = nil) {
|
|
7
|
-
val = serializer_instance.instance_eval(&inner)
|
|
8
|
-
if Graphiti.config.typecast_reads && inner.nil?
|
|
9
|
-
typecast_ref.call(val)
|
|
10
|
-
else
|
|
11
|
-
val
|
|
12
|
-
end
|
|
13
|
-
}
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
1
|
+
module Graphiti::ActiveGraph
|
|
2
|
+
module Util
|
|
3
|
+
module SerializerAttribute
|
|
4
|
+
def wrap_proc(inner)
|
|
5
|
+
typecast_ref = typecast(Graphiti::Types[@attr[:type]][:read])
|
|
6
|
+
->(serializer_instance = nil) {
|
|
7
|
+
val = serializer_instance.instance_eval(&inner)
|
|
8
|
+
if Graphiti.config.typecast_reads && inner.nil?
|
|
9
|
+
typecast_ref.call(val)
|
|
10
|
+
else
|
|
11
|
+
val
|
|
12
|
+
end
|
|
13
|
+
}
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
module Graphiti::ActiveGraph
|
|
2
|
-
module Util
|
|
3
|
-
module SerializerRelationship
|
|
4
|
-
def data_proc
|
|
5
|
-
sideload_ref = @sideload
|
|
6
|
-
->(_) {
|
|
7
|
-
# use custom assigned sideload if it is specified via "assign_each_proc"
|
|
8
|
-
# otherwise retrieve sideload using normal getter on parent object
|
|
9
|
-
records = if custom_proc = sideload_ref.assign_each_proc
|
|
10
|
-
custom_proc.call(@object)
|
|
11
|
-
else
|
|
12
|
-
@object.public_send(sideload_ref.association_name)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
if records
|
|
16
|
-
if records.respond_to?(:to_ary)
|
|
17
|
-
records.each { |r| sideload_ref.resource.decorate_record(r) }
|
|
18
|
-
else
|
|
19
|
-
sideload_ref.resource.decorate_record(records)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
records
|
|
23
|
-
end
|
|
24
|
-
}
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
1
|
+
module Graphiti::ActiveGraph
|
|
2
|
+
module Util
|
|
3
|
+
module SerializerRelationship
|
|
4
|
+
def data_proc
|
|
5
|
+
sideload_ref = @sideload
|
|
6
|
+
->(_) {
|
|
7
|
+
# use custom assigned sideload if it is specified via "assign_each_proc"
|
|
8
|
+
# otherwise retrieve sideload using normal getter on parent object
|
|
9
|
+
records = if custom_proc = sideload_ref.assign_each_proc
|
|
10
|
+
custom_proc.call(@object)
|
|
11
|
+
else
|
|
12
|
+
@object.public_send(sideload_ref.association_name)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
if records
|
|
16
|
+
if records.respond_to?(:to_ary)
|
|
17
|
+
records.each { |r| sideload_ref.resource.decorate_record(r) }
|
|
18
|
+
else
|
|
19
|
+
sideload_ref.resource.decorate_record(records)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
records
|
|
23
|
+
end
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
module Graphiti::ActiveGraph
|
|
2
|
-
module Util
|
|
3
|
-
module Transformers
|
|
4
|
-
class RelationParam
|
|
5
|
-
attr_reader :map
|
|
6
|
-
|
|
7
|
-
def initialize(relation_param_str)
|
|
8
|
-
@map = Graphiti::ActiveGraph::Util::Parsers::RelChain.new.rel_param_rule.parse(relation_param_str.to_s)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def split_rel_length(retain_rel_limit)
|
|
12
|
-
rel_name_part = if retain_rel_limit
|
|
13
|
-
(rel_limit || '') + rel_name
|
|
14
|
-
else
|
|
15
|
-
rel_name_sym
|
|
16
|
-
end
|
|
17
|
-
[rel_name_part.to_sym, rel_length_number]
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def rel_name_n_length
|
|
21
|
-
"#{rel_name}#{rel_length}"
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def rel_limit(limit_part = nil)
|
|
25
|
-
join(limit_part || map[:limit_part])
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def rel_limit_number
|
|
29
|
-
rel_limit(map[:limit_part]&.except(:limit_ast))
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def rel_name
|
|
33
|
-
map[:rel_name].to_s
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def rel_name_sym
|
|
37
|
-
rel_name.to_sym
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def rel_length(length_part = nil)
|
|
41
|
-
join(length_part || map[:length_part])
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def rel_length_number
|
|
45
|
-
rel_length(map[:length_part]&.except(:ast))
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
private
|
|
49
|
-
|
|
50
|
-
def join(hash)
|
|
51
|
-
hash&.values&.map(&:to_s)&.join
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
end
|
|
1
|
+
module Graphiti::ActiveGraph
|
|
2
|
+
module Util
|
|
3
|
+
module Transformers
|
|
4
|
+
class RelationParam
|
|
5
|
+
attr_reader :map
|
|
6
|
+
|
|
7
|
+
def initialize(relation_param_str)
|
|
8
|
+
@map = Graphiti::ActiveGraph::Util::Parsers::RelChain.new.rel_param_rule.parse(relation_param_str.to_s)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def split_rel_length(retain_rel_limit)
|
|
12
|
+
rel_name_part = if retain_rel_limit
|
|
13
|
+
(rel_limit || '') + rel_name
|
|
14
|
+
else
|
|
15
|
+
rel_name_sym
|
|
16
|
+
end
|
|
17
|
+
[rel_name_part.to_sym, rel_length_number]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def rel_name_n_length
|
|
21
|
+
"#{rel_name}#{rel_length}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def rel_limit(limit_part = nil)
|
|
25
|
+
join(limit_part || map[:limit_part])
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def rel_limit_number
|
|
29
|
+
rel_limit(map[:limit_part]&.except(:limit_ast))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def rel_name
|
|
33
|
+
map[:rel_name].to_s
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def rel_name_sym
|
|
37
|
+
rel_name.to_sym
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def rel_length(length_part = nil)
|
|
41
|
+
join(length_part || map[:length_part])
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def rel_length_number
|
|
45
|
+
rel_length(map[:length_part]&.except(:ast))
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def join(hash)
|
|
51
|
+
hash&.values&.map(&:to_s)&.join
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
module Graphiti
|
|
2
|
-
module ActiveGraph
|
|
3
|
-
VERSION = '1.3.
|
|
4
|
-
end
|
|
5
|
-
end
|
|
1
|
+
module Graphiti
|
|
2
|
+
module ActiveGraph
|
|
3
|
+
VERSION = '1.3.2'
|
|
4
|
+
end
|
|
5
|
+
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
module Graphiti
|
|
2
|
-
module SidepostConfiguration
|
|
3
|
-
extend ActiveSupport::Concern
|
|
4
|
-
|
|
5
|
-
included do
|
|
6
|
-
attr_accessor :allow_sidepost
|
|
7
|
-
end
|
|
8
|
-
end
|
|
9
|
-
end
|
|
1
|
+
module Graphiti
|
|
2
|
+
module SidepostConfiguration
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
attr_accessor :allow_sidepost
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|