graphiti 1.0.rc.21 → 1.0.rc.22
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.standard.yml +14 -0
- data/.travis.yml +31 -2
- data/Appraisals +16 -10
- data/Gemfile +5 -5
- data/Guardfile +2 -2
- data/README.md +1 -1
- data/Rakefile +4 -4
- data/exe/graphiti +1 -1
- data/gemfiles/rails_4.gemfile +0 -1
- data/gemfiles/rails_5.gemfile +0 -1
- data/gemfiles/rails_6.gemfile +19 -0
- data/graphiti.gemspec +15 -14
- data/lib/generators/graphiti/api_test_generator.rb +16 -16
- data/lib/generators/graphiti/generator_mixin.rb +7 -7
- data/lib/generators/graphiti/install_generator.rb +19 -19
- data/lib/generators/graphiti/resource_generator.rb +19 -19
- data/lib/generators/graphiti/resource_test_generator.rb +10 -10
- data/lib/graphiti.rb +24 -26
- data/lib/graphiti/adapters/abstract.rb +25 -39
- data/lib/graphiti/adapters/active_record.rb +43 -49
- data/lib/graphiti/adapters/active_record/many_to_many_sideload.rb +33 -11
- data/lib/graphiti/adapters/graphiti_api.rb +16 -16
- data/lib/graphiti/adapters/null.rb +0 -12
- data/lib/graphiti/cli.rb +7 -7
- data/lib/graphiti/configuration.rb +14 -15
- data/lib/graphiti/context.rb +1 -1
- data/lib/graphiti/debugger.rb +22 -26
- data/lib/graphiti/delegates/pagination.rb +9 -9
- data/lib/graphiti/deserializer.rb +7 -9
- data/lib/graphiti/errors.rb +119 -119
- data/lib/graphiti/extensions/boolean_attribute.rb +1 -1
- data/lib/graphiti/extensions/extra_attribute.rb +1 -1
- data/lib/graphiti/extensions/temp_id.rb +1 -1
- data/lib/graphiti/filter_operators.rb +6 -0
- data/lib/graphiti/hash_renderer.rb +15 -15
- data/lib/graphiti/jsonapi_serializable_ext.rb +1 -1
- data/lib/graphiti/query.rb +35 -35
- data/lib/graphiti/railtie.rb +14 -10
- data/lib/graphiti/renderer.rb +2 -2
- data/lib/graphiti/resource.rb +4 -6
- data/lib/graphiti/resource/configuration.rb +9 -13
- data/lib/graphiti/resource/documentation.rb +4 -2
- data/lib/graphiti/resource/dsl.rb +21 -25
- data/lib/graphiti/resource/interface.rb +3 -3
- data/lib/graphiti/resource/links.rb +14 -14
- data/lib/graphiti/resource/persistence.rb +9 -9
- data/lib/graphiti/resource/polymorphism.rb +3 -3
- data/lib/graphiti/resource/remote.rb +3 -3
- data/lib/graphiti/resource/sideloading.rb +5 -5
- data/lib/graphiti/resource_proxy.rb +12 -12
- data/lib/graphiti/schema.rb +27 -26
- data/lib/graphiti/schema_diff.rb +10 -10
- data/lib/graphiti/scope.rb +12 -16
- data/lib/graphiti/scoping/base.rb +5 -5
- data/lib/graphiti/scoping/default_filter.rb +1 -1
- data/lib/graphiti/scoping/filter.rb +15 -24
- data/lib/graphiti/scoping/filterable.rb +5 -5
- data/lib/graphiti/scoping/paginate.rb +1 -1
- data/lib/graphiti/scoping/sort.rb +7 -7
- data/lib/graphiti/serializer.rb +8 -4
- data/lib/graphiti/sideload.rb +23 -39
- data/lib/graphiti/sideload/belongs_to.rb +2 -2
- data/lib/graphiti/sideload/has_many.rb +1 -1
- data/lib/graphiti/sideload/many_to_many.rb +18 -2
- data/lib/graphiti/sideload/polymorphic_belongs_to.rb +14 -8
- data/lib/graphiti/stats/dsl.rb +7 -1
- data/lib/graphiti/tasks.rb +10 -10
- data/lib/graphiti/types.rb +98 -98
- data/lib/graphiti/util/attribute_check.rb +1 -1
- data/lib/graphiti/util/class.rb +3 -3
- data/lib/graphiti/util/field_params.rb +1 -1
- data/lib/graphiti/util/hash.rb +19 -1
- data/lib/graphiti/util/link.rb +15 -19
- data/lib/graphiti/util/persistence.rb +17 -22
- data/lib/graphiti/util/relationship_payload.rb +2 -2
- data/lib/graphiti/util/remote_params.rb +12 -12
- data/lib/graphiti/util/remote_serializer.rb +2 -2
- data/lib/graphiti/util/serializer_attributes.rb +20 -25
- data/lib/graphiti/util/serializer_relationships.rb +17 -18
- data/lib/graphiti/util/sideload.rb +1 -1
- data/lib/graphiti/util/transaction_hooks_recorder.rb +3 -2
- data/lib/graphiti/version.rb +1 -1
- metadata +22 -6
data/lib/graphiti/schema_diff.rb
CHANGED
@@ -49,7 +49,7 @@ module Graphiti
|
|
49
49
|
|
50
50
|
def compare_attributes(old_resource, new_resource)
|
51
51
|
old_resource[:attributes].each_pair do |name, old_att|
|
52
|
-
unless new_att = new_resource[:attributes][name]
|
52
|
+
unless (new_att = new_resource[:attributes][name])
|
53
53
|
@errors << "#{old_resource[:name]}: attribute #{name.inspect} was removed."
|
54
54
|
next
|
55
55
|
end
|
@@ -90,7 +90,7 @@ module Graphiti
|
|
90
90
|
|
91
91
|
def compare_relationships(old_resource, new_resource)
|
92
92
|
old_resource[:relationships].each_pair do |name, old_rel|
|
93
|
-
unless new_rel = new_resource[:relationships][name]
|
93
|
+
unless (new_rel = new_resource[:relationships][name])
|
94
94
|
@errors << "#{old_resource[:name]}: relationship #{name.inspect} was removed."
|
95
95
|
next
|
96
96
|
end
|
@@ -112,7 +112,7 @@ module Graphiti
|
|
112
112
|
|
113
113
|
def compare_extra_attributes(old_resource, new_resource)
|
114
114
|
old_resource[:extra_attributes].each_pair do |name, old_att|
|
115
|
-
unless new_att = new_resource[:extra_attributes][name]
|
115
|
+
unless (new_att = new_resource[:extra_attributes][name])
|
116
116
|
@errors << "#{old_resource[:name]}: extra attribute #{name.inspect} was removed."
|
117
117
|
next
|
118
118
|
end
|
@@ -123,7 +123,7 @@ module Graphiti
|
|
123
123
|
|
124
124
|
def compare_sorts(old_resource, new_resource)
|
125
125
|
old_resource[:sorts].each_pair do |name, old_sort|
|
126
|
-
unless new_sort = new_resource[:sorts][name]
|
126
|
+
unless (new_sort = new_resource[:sorts][name])
|
127
127
|
@errors << "#{old_resource[:name]}: sort #{name.inspect} was removed."
|
128
128
|
next
|
129
129
|
end
|
@@ -146,7 +146,7 @@ module Graphiti
|
|
146
146
|
|
147
147
|
def compare_filters(old_resource, new_resource)
|
148
148
|
old_resource[:filters].each_pair do |name, old_filter|
|
149
|
-
unless new_filter = new_resource[:filters][name]
|
149
|
+
unless (new_filter = new_resource[:filters][name])
|
150
150
|
@errors << "#{old_resource[:name]}: filter #{name.inspect} was removed."
|
151
151
|
next
|
152
152
|
end
|
@@ -206,13 +206,13 @@ module Graphiti
|
|
206
206
|
|
207
207
|
def compare_endpoints
|
208
208
|
@old[:endpoints].each_pair do |path, old_endpoint|
|
209
|
-
unless new_endpoint = @new[:endpoints][path]
|
209
|
+
unless (new_endpoint = @new[:endpoints][path])
|
210
210
|
@errors << "Endpoint \"#{path}\" was removed."
|
211
211
|
next
|
212
212
|
end
|
213
213
|
|
214
214
|
old_endpoint[:actions].each_pair do |name, old_action|
|
215
|
-
unless new_action = new_endpoint[:actions][name]
|
215
|
+
unless (new_action = new_endpoint[:actions][name])
|
216
216
|
@errors << "Endpoint \"#{path}\" removed action #{name.inspect}."
|
217
217
|
next
|
218
218
|
end
|
@@ -236,7 +236,7 @@ module Graphiti
|
|
236
236
|
|
237
237
|
def compare_types
|
238
238
|
@old[:types].each_pair do |name, old_type|
|
239
|
-
unless new_type = @new[:types][name]
|
239
|
+
unless (new_type = @new[:types][name])
|
240
240
|
@errors << "Type #{name.inspect} was removed."
|
241
241
|
next
|
242
242
|
end
|
@@ -255,11 +255,11 @@ module Graphiti
|
|
255
255
|
end
|
256
256
|
|
257
257
|
[:readable, :writable].each do |flag|
|
258
|
-
if [true,
|
258
|
+
if [true, "guarded"].include?(old_att[flag]) && new_att[flag] == false
|
259
259
|
@errors << "#{resource_name}: #{prefix} #{att_name.inspect} changed flag #{flag.inspect} from #{old_att[flag].inspect} to #{new_att[flag].inspect}."
|
260
260
|
end
|
261
261
|
|
262
|
-
if new_att[flag] ==
|
262
|
+
if new_att[flag] == "guarded" && old_att[flag] == true
|
263
263
|
@errors << "#{resource_name}: #{prefix} #{att_name.inspect} changed flag #{flag.inspect} from #{old_att[flag].inspect} to #{new_att[flag].inspect}."
|
264
264
|
end
|
265
265
|
end
|
data/lib/graphiti/scope.rb
CHANGED
@@ -8,26 +8,24 @@ module Graphiti
|
|
8
8
|
@query = query
|
9
9
|
@opts = opts
|
10
10
|
|
11
|
-
@object = @resource.around_scoping(@object, @query.hash)
|
11
|
+
@object = @resource.around_scoping(@object, @query.hash) { |scope|
|
12
12
|
apply_scoping(scope, opts)
|
13
|
-
|
13
|
+
}
|
14
14
|
end
|
15
15
|
|
16
16
|
def resolve
|
17
17
|
if @query.zero_results?
|
18
18
|
[]
|
19
19
|
else
|
20
|
-
resolved = broadcast_data
|
20
|
+
resolved = broadcast_data { |payload|
|
21
21
|
@object = @resource.before_resolve(@object, @query)
|
22
22
|
payload[:results] = @resource.resolve(@object)
|
23
23
|
payload[:results]
|
24
|
-
|
24
|
+
}
|
25
25
|
resolved.compact!
|
26
26
|
assign_serializer(resolved)
|
27
27
|
yield resolved if block_given?
|
28
|
-
|
29
|
-
@opts[:after_resolve].call(resolved)
|
30
|
-
end
|
28
|
+
@opts[:after_resolve]&.call(resolved)
|
31
29
|
resolve_sideloads(resolved) unless @query.sideloads.empty?
|
32
30
|
resolved
|
33
31
|
end
|
@@ -42,11 +40,11 @@ module Graphiti
|
|
42
40
|
@query.sideloads.each_pair do |name, q|
|
43
41
|
sideload = @resource.class.sideload(name)
|
44
42
|
next if sideload.nil? || sideload.shared_remote?
|
45
|
-
|
46
|
-
|
43
|
+
parent_resource = @resource
|
44
|
+
graphiti_context = Graphiti.context
|
47
45
|
resolve_sideload = -> {
|
48
|
-
Graphiti.context =
|
49
|
-
sideload.resolve(results, q,
|
46
|
+
Graphiti.context = graphiti_context
|
47
|
+
sideload.resolve(results, q, parent_resource)
|
50
48
|
if concurrent && defined?(ActiveRecord)
|
51
49
|
ActiveRecord::Base.clear_active_connections!
|
52
50
|
end
|
@@ -60,13 +58,11 @@ module Graphiti
|
|
60
58
|
|
61
59
|
if concurrent
|
62
60
|
# Wait for all promises to finish
|
63
|
-
|
64
|
-
sleep 0.01
|
65
|
-
end
|
61
|
+
sleep 0.01 until promises.all? { |p| p.fulfilled? || p.rejected? }
|
66
62
|
# Re-raise the error with correct stacktrace
|
67
63
|
# OPTION** to avoid failing here?? if so need serializable patch
|
68
64
|
# to avoid loading data when association not loaded
|
69
|
-
if rejected = promises.find(&:rejected?)
|
65
|
+
if (rejected = promises.find(&:rejected?))
|
70
66
|
raise rejected.reason
|
71
67
|
end
|
72
68
|
end
|
@@ -79,7 +75,7 @@ module Graphiti
|
|
79
75
|
resource: @resource,
|
80
76
|
params: @opts[:params],
|
81
77
|
sideload: @opts[:sideload],
|
82
|
-
parent: @opts[:parent]
|
78
|
+
parent: @opts[:parent],
|
83
79
|
}
|
84
80
|
Graphiti.broadcast("data", opts) do |payload|
|
85
81
|
yield payload
|
@@ -67,13 +67,13 @@ module Graphiti
|
|
67
67
|
|
68
68
|
# Defines how to call/apply the default scoping logic
|
69
69
|
def apply_standard_scope
|
70
|
-
raise
|
70
|
+
raise "override in subclass"
|
71
71
|
end
|
72
72
|
|
73
73
|
# Defines how to call/apply the custom scoping logic provided by the
|
74
74
|
# user.
|
75
75
|
def apply_custom_scope
|
76
|
-
raise
|
76
|
+
raise "override in subclass"
|
77
77
|
end
|
78
78
|
|
79
79
|
private
|
@@ -81,10 +81,10 @@ module Graphiti
|
|
81
81
|
# If the user customized (by providing a block in the Resource DSL)
|
82
82
|
# then call the custom proc. Else, call the default proc.
|
83
83
|
def apply_standard_or_override
|
84
|
-
if apply_standard_scope?
|
85
|
-
|
84
|
+
@scope = if apply_standard_scope?
|
85
|
+
apply_standard_scope
|
86
86
|
else
|
87
|
-
|
87
|
+
apply_custom_scope
|
88
88
|
end
|
89
89
|
|
90
90
|
@scope
|
@@ -22,7 +22,7 @@ module Graphiti
|
|
22
22
|
private
|
23
23
|
|
24
24
|
def filter_scope(filter, operator, value)
|
25
|
-
if custom_scope = filter.values[0][:operators][operator]
|
25
|
+
if (custom_scope = filter.values[0][:operators][operator])
|
26
26
|
custom_scope.call(@scope, value, resource.context)
|
27
27
|
else
|
28
28
|
filter_via_adapter(filter, operator, value)
|
@@ -46,7 +46,7 @@ module Graphiti
|
|
46
46
|
filter_param.each_pair do |param_name, param_value|
|
47
47
|
filter = find_filter!(param_name)
|
48
48
|
value, operator = normalize_param(filter, param_value)
|
49
|
-
operator = operator.to_s.gsub(
|
49
|
+
operator = operator.to_s.gsub("!", "not_").to_sym
|
50
50
|
validate_operator(filter, operator)
|
51
51
|
unless filter.values[0][:type] == :hash || !value.is_a?(String)
|
52
52
|
value = parse_string_value(filter.values[0], value)
|
@@ -62,7 +62,7 @@ module Graphiti
|
|
62
62
|
|
63
63
|
def coerce_types(filter, name, value)
|
64
64
|
type_name = filter[:type]
|
65
|
-
is_array = type_name.to_s.starts_with?(
|
65
|
+
is_array = type_name.to_s.starts_with?("array_of") ||
|
66
66
|
Types[type_name][:canonical_name] == :array
|
67
67
|
|
68
68
|
if is_array
|
@@ -75,7 +75,7 @@ module Graphiti
|
|
75
75
|
|
76
76
|
def normalize_param(filter, param_value)
|
77
77
|
unless param_value.is_a?(Hash) && param_value.present?
|
78
|
-
param_value = {
|
78
|
+
param_value = {eq: param_value}
|
79
79
|
end
|
80
80
|
value = param_value.values.first
|
81
81
|
operator = param_value.keys.first
|
@@ -106,7 +106,7 @@ module Graphiti
|
|
106
106
|
|
107
107
|
def validate_allowlist(resource, filter, values)
|
108
108
|
values.each do |v|
|
109
|
-
if allow = filter.values[0][:allow]
|
109
|
+
if (allow = filter.values[0][:allow])
|
110
110
|
unless allow.include?(v)
|
111
111
|
raise Errors::InvalidFilterValue.new(resource, filter, v)
|
112
112
|
end
|
@@ -116,7 +116,7 @@ module Graphiti
|
|
116
116
|
|
117
117
|
def validate_denylist(resource, filter, values)
|
118
118
|
values.each do |v|
|
119
|
-
if deny = filter.values[0][:deny]
|
119
|
+
if (deny = filter.values[0][:deny])
|
120
120
|
if deny.include?(v)
|
121
121
|
raise Errors::InvalidFilterValue.new(resource, filter, v)
|
122
122
|
end
|
@@ -131,19 +131,10 @@ module Graphiti
|
|
131
131
|
end
|
132
132
|
|
133
133
|
if value.is_a?(String)
|
134
|
-
value = value.gsub(
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
value = value.split('},{').map do |v|
|
139
|
-
if v.starts_with?('{') && !v.ends_with?('}')
|
140
|
-
v = "#{v}}"
|
141
|
-
elsif v.ends_with?('}') && !v.starts_with?('{')
|
142
|
-
v = "{#{v}"
|
143
|
-
else
|
144
|
-
"{#{v}}"
|
145
|
-
end
|
146
|
-
end
|
134
|
+
value = value.gsub("{{{", "{").gsub("}}}", "}")
|
135
|
+
|
136
|
+
if value.include?("},{") && !filter.values[0][:single]
|
137
|
+
value = Util::Hash.split_json(value)
|
147
138
|
end
|
148
139
|
end
|
149
140
|
|
@@ -162,13 +153,13 @@ module Graphiti
|
|
162
153
|
type = Graphiti::Types[filter[:type]]
|
163
154
|
array_or_string = [:string, :array].include?(type[:canonical_name])
|
164
155
|
if (arr = value.scan(/\[.*?\]/)).present? && array_or_string
|
165
|
-
value = arr.map
|
156
|
+
value = arr.map { |json|
|
166
157
|
begin
|
167
158
|
JSON.parse(json)
|
168
159
|
rescue
|
169
160
|
raise Errors::InvalidJSONArray.new(resource, value)
|
170
161
|
end
|
171
|
-
|
162
|
+
}
|
172
163
|
value = value[0] if value.length == 1
|
173
164
|
else
|
174
165
|
value = parse_string_arrays(value)
|
@@ -180,11 +171,11 @@ module Graphiti
|
|
180
171
|
# Find the quoted strings
|
181
172
|
quotes = value.scan(/{{.*?}}/)
|
182
173
|
# remove them from the rest
|
183
|
-
quotes.each { |q| value.gsub!(q,
|
174
|
+
quotes.each { |q| value.gsub!(q, "") }
|
184
175
|
# remove the quote characters from the quoted strings
|
185
|
-
quotes.each { |q| q.gsub!(
|
176
|
+
quotes.each { |q| q.gsub!("{{", "").gsub!("}}", "") }
|
186
177
|
# merge everything back together into an array
|
187
|
-
value = Array(value.split(
|
178
|
+
value = Array(value.split(",")) + quotes
|
188
179
|
# remove any blanks that are left
|
189
180
|
value.reject! { |v| v.length.zero? }
|
190
181
|
value = value[0] if value.length == 1
|
@@ -11,7 +11,7 @@ module Graphiti
|
|
11
11
|
# @api private
|
12
12
|
def find_filter!(name)
|
13
13
|
resource.class.get_attr!(name, :filterable, request: true)
|
14
|
-
{
|
14
|
+
{name => resource.filters[name]}
|
15
15
|
end
|
16
16
|
|
17
17
|
# @api private
|
@@ -24,18 +24,18 @@ module Graphiti
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def required_filters
|
27
|
-
resource.filters.map
|
27
|
+
resource.filters.map { |k, v|
|
28
28
|
k if v[:required]
|
29
|
-
|
29
|
+
}.compact
|
30
30
|
end
|
31
31
|
|
32
32
|
def missing_dependent_filters
|
33
33
|
[].tap do |arr|
|
34
34
|
filter_param.each_pair do |key, value|
|
35
|
-
if df = dependent_filters[key]
|
35
|
+
if (df = dependent_filters[key])
|
36
36
|
missing = df[:dependencies] - filter_param.keys
|
37
37
|
unless missing.length.zero?
|
38
|
-
arr << {
|
38
|
+
arr << {filter: df, missing: missing}
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
@@ -28,10 +28,10 @@ module Graphiti
|
|
28
28
|
raise Errors::UnsupportedSort.new resource,
|
29
29
|
attribute, sort[:only], direction
|
30
30
|
else
|
31
|
-
if sort[:proc]
|
32
|
-
|
31
|
+
@scope = if sort[:proc]
|
32
|
+
sort[:proc].call(@scope, direction)
|
33
33
|
else
|
34
|
-
|
34
|
+
resource.adapter.order(@scope, attribute, direction)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -70,17 +70,17 @@ module Graphiti
|
|
70
70
|
|
71
71
|
def normalize(sort)
|
72
72
|
return sort if sort.is_a?(Array)
|
73
|
-
sorts = sort.split(
|
73
|
+
sorts = sort.split(",")
|
74
74
|
sorts.map do |s|
|
75
75
|
sort_hash(s)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
79
|
def sort_hash(attr)
|
80
|
-
value = attr[0] ==
|
81
|
-
key = attr.sub(
|
80
|
+
value = attr[0] == "-" ? :desc : :asc
|
81
|
+
key = attr.sub("-", "").to_sym
|
82
82
|
|
83
|
-
{
|
83
|
+
{key => value}
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
data/lib/graphiti/serializer.rb
CHANGED
@@ -43,18 +43,22 @@ module Graphiti
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
def respond_to_missing?(method_name, include_private = true)
|
47
|
+
@resource.respond_to?(method_name, include_private) || super
|
48
|
+
end
|
49
|
+
|
46
50
|
private
|
47
51
|
|
48
52
|
def strip_relationships!(hash)
|
49
|
-
hash[:relationships]
|
50
|
-
payload.
|
51
|
-
end
|
53
|
+
hash[:relationships]&.select! do |name, payload|
|
54
|
+
payload.key?(:data)
|
55
|
+
end
|
52
56
|
end
|
53
57
|
|
54
58
|
def strip_relationships?
|
55
59
|
return false unless Graphiti.config.links_on_demand
|
56
60
|
params = Graphiti.context[:object].params || {}
|
57
|
-
[false, nil,
|
61
|
+
[false, nil, "false"].include?(params[:links])
|
58
62
|
end
|
59
63
|
end
|
60
64
|
end
|
data/lib/graphiti/sideload.rb
CHANGED
@@ -4,14 +4,10 @@ module Graphiti
|
|
4
4
|
TYPES = [:has_many, :belongs_to, :has_one, :many_to_many]
|
5
5
|
|
6
6
|
attr_reader :name,
|
7
|
-
:resource_class,
|
8
7
|
:parent_resource_class,
|
9
|
-
:foreign_key,
|
10
|
-
:primary_key,
|
11
8
|
:parent,
|
12
9
|
:group_name,
|
13
10
|
:link,
|
14
|
-
:description,
|
15
11
|
:polymorphic_as
|
16
12
|
|
17
13
|
class_attribute :scope_proc,
|
@@ -22,7 +18,7 @@ module Graphiti
|
|
22
18
|
:link_proc
|
23
19
|
|
24
20
|
def initialize(name, opts)
|
25
|
-
@name
|
21
|
+
@name = name
|
26
22
|
validate_options!(opts)
|
27
23
|
@parent_resource_class = opts[:parent_resource]
|
28
24
|
@resource_class = opts[:resource]
|
@@ -81,15 +77,15 @@ module Graphiti
|
|
81
77
|
end
|
82
78
|
|
83
79
|
def create_remote_resource
|
84
|
-
|
85
|
-
klass = Class.new(Graphiti::Resource)
|
80
|
+
remote_url = @remote
|
81
|
+
klass = Class.new(Graphiti::Resource) {
|
86
82
|
self.adapter = Graphiti::Adapters::GraphitiAPI
|
87
83
|
self.model = OpenStruct
|
88
|
-
self.remote =
|
84
|
+
self.remote = remote_url
|
89
85
|
self.validate_endpoints = false
|
90
|
-
|
86
|
+
}
|
91
87
|
name = "#{parent_resource_class.name}.#{@name}.remote"
|
92
|
-
klass.class_eval("def self.name;'#{name}';end")
|
88
|
+
klass.class_eval("def self.name;'#{name}';end", __FILE__, __LINE__)
|
93
89
|
klass
|
94
90
|
end
|
95
91
|
|
@@ -163,7 +159,7 @@ module Graphiti
|
|
163
159
|
end
|
164
160
|
|
165
161
|
def assign_each(parent, children)
|
166
|
-
raise
|
162
|
+
raise "Override #assign_each in subclass"
|
167
163
|
end
|
168
164
|
|
169
165
|
def type
|
@@ -171,7 +167,7 @@ module Graphiti
|
|
171
167
|
end
|
172
168
|
|
173
169
|
def load_params(parents, query)
|
174
|
-
raise
|
170
|
+
raise "Override #load_params in subclass"
|
175
171
|
end
|
176
172
|
|
177
173
|
def description
|
@@ -189,13 +185,13 @@ module Graphiti
|
|
189
185
|
|
190
186
|
def load(parents, query, graph_parent)
|
191
187
|
params = load_params(parents, query)
|
192
|
-
params_proc
|
188
|
+
params_proc&.call(params, parents)
|
193
189
|
return [] if blank_query?(params)
|
194
190
|
opts = load_options(parents, query)
|
195
191
|
opts[:sideload] = self
|
196
192
|
opts[:parent] = graph_parent
|
197
193
|
proxy = resource.class._all(params, opts, base_scope)
|
198
|
-
pre_load_proc
|
194
|
+
pre_load_proc&.call(proxy, parents)
|
199
195
|
proxy.to_a
|
200
196
|
end
|
201
197
|
|
@@ -203,7 +199,7 @@ module Graphiti
|
|
203
199
|
def infer_foreign_key
|
204
200
|
model = parent_resource_class.model
|
205
201
|
namespace = namespace_for(model)
|
206
|
-
model_name = model.name.gsub("#{namespace}::",
|
202
|
+
model_name = model.name.gsub("#{namespace}::", "")
|
207
203
|
:"#{model_name.underscore}_id"
|
208
204
|
end
|
209
205
|
|
@@ -223,10 +219,10 @@ module Graphiti
|
|
223
219
|
end
|
224
220
|
|
225
221
|
parents.each do |parent|
|
226
|
-
if performant_assign?
|
227
|
-
|
222
|
+
relevant_children = if performant_assign?
|
223
|
+
children_for(parent, map) || []
|
228
224
|
else
|
229
|
-
|
225
|
+
fire_assign_each(parent, children)
|
230
226
|
end
|
231
227
|
|
232
228
|
if relevant_children.is_a?(Array)
|
@@ -317,19 +313,17 @@ module Graphiti
|
|
317
313
|
|
318
314
|
# @api private
|
319
315
|
def resource_class_loaded?
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
false
|
325
|
-
end
|
316
|
+
resource_class
|
317
|
+
true
|
318
|
+
rescue Graphiti::Errors::ResourceNotFound
|
319
|
+
false
|
326
320
|
end
|
327
321
|
|
328
322
|
private
|
329
323
|
|
330
324
|
def blank_query?(params)
|
331
|
-
if filter = params[:filter]
|
332
|
-
if filter.values == [
|
325
|
+
if (filter = params[:filter])
|
326
|
+
if filter.values == [""]
|
333
327
|
return true
|
334
328
|
end
|
335
329
|
end
|
@@ -339,21 +333,11 @@ module Graphiti
|
|
339
333
|
def validate_options!(opts)
|
340
334
|
if opts[:remote]
|
341
335
|
if opts[:resource]
|
342
|
-
raise Errors::SideloadConfig.new(@name, opts[:parent_resource],
|
336
|
+
raise Errors::SideloadConfig.new(@name, opts[:parent_resource], "cannot pass :remote and :resource options together")
|
343
337
|
end
|
344
338
|
|
345
339
|
if opts[:link]
|
346
|
-
raise Errors::SideloadConfig.new(@name, opts[:parent_resource],
|
347
|
-
end
|
348
|
-
end
|
349
|
-
end
|
350
|
-
|
351
|
-
def apply_belongs_to_many_filter
|
352
|
-
_self = self
|
353
|
-
fk_type = parent_resource_class.attributes[:id][:type]
|
354
|
-
resource_class.filter true_foreign_key, fk_type do
|
355
|
-
eq do |scope, value|
|
356
|
-
_self.belongs_to_many_filter(scope, value)
|
340
|
+
raise Errors::SideloadConfig.new(@name, opts[:parent_resource], "remote sideloads do not currently support :link")
|
357
341
|
end
|
358
342
|
end
|
359
343
|
end
|
@@ -391,7 +375,7 @@ module Graphiti
|
|
391
375
|
instance_exec(parent_ids, parents, &self.class.scope_proc)
|
392
376
|
else
|
393
377
|
method = method(:scope)
|
394
|
-
if [2
|
378
|
+
if [2, -2].include?(method.arity)
|
395
379
|
scope(parent_ids, parents)
|
396
380
|
else
|
397
381
|
scope(parent_ids)
|