jsonapi-resources 0.10.7 → 0.11.0.beta2
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/LICENSE.txt +1 -1
- data/README.md +39 -2
- data/lib/generators/jsonapi/controller_generator.rb +2 -0
- data/lib/generators/jsonapi/resource_generator.rb +2 -0
- data/lib/jsonapi/active_relation/adapters/join_left_active_record_adapter.rb +3 -2
- data/lib/jsonapi/active_relation/join_manager.rb +30 -18
- data/lib/jsonapi/active_relation/join_manager_v10.rb +305 -0
- data/lib/jsonapi/active_relation_retrieval.rb +885 -0
- data/lib/jsonapi/active_relation_retrieval_v09.rb +715 -0
- data/lib/jsonapi/{active_relation_resource.rb → active_relation_retrieval_v10.rb} +113 -135
- data/lib/jsonapi/acts_as_resource_controller.rb +49 -49
- data/lib/jsonapi/cached_response_fragment.rb +4 -2
- data/lib/jsonapi/callbacks.rb +2 -0
- data/lib/jsonapi/compiled_json.rb +2 -0
- data/lib/jsonapi/configuration.rb +35 -15
- data/lib/jsonapi/error.rb +2 -0
- data/lib/jsonapi/error_codes.rb +2 -0
- data/lib/jsonapi/exceptions.rb +2 -0
- data/lib/jsonapi/formatter.rb +2 -0
- data/lib/jsonapi/include_directives.rb +77 -19
- data/lib/jsonapi/link_builder.rb +2 -0
- data/lib/jsonapi/mime_types.rb +6 -10
- data/lib/jsonapi/naive_cache.rb +2 -0
- data/lib/jsonapi/operation.rb +2 -0
- data/lib/jsonapi/operation_result.rb +2 -0
- data/lib/jsonapi/paginator.rb +2 -17
- data/lib/jsonapi/path.rb +2 -0
- data/lib/jsonapi/path_segment.rb +4 -2
- data/lib/jsonapi/processor.rb +100 -153
- data/lib/jsonapi/relationship.rb +89 -35
- data/lib/jsonapi/{request_parser.rb → request.rb} +157 -164
- data/lib/jsonapi/resource.rb +7 -2
- data/lib/jsonapi/{basic_resource.rb → resource_common.rb} +187 -88
- data/lib/jsonapi/resource_controller.rb +2 -0
- data/lib/jsonapi/resource_controller_metal.rb +2 -0
- data/lib/jsonapi/resource_fragment.rb +17 -15
- data/lib/jsonapi/resource_identity.rb +6 -0
- data/lib/jsonapi/resource_serializer.rb +20 -4
- data/lib/jsonapi/resource_set.rb +36 -16
- data/lib/jsonapi/resource_tree.rb +191 -0
- data/lib/jsonapi/resources/railtie.rb +3 -1
- data/lib/jsonapi/resources/version.rb +3 -1
- data/lib/jsonapi/response_document.rb +4 -2
- data/lib/jsonapi/routing_ext.rb +4 -2
- data/lib/jsonapi/simple_resource.rb +13 -0
- data/lib/jsonapi-resources.rb +10 -4
- data/lib/tasks/check_upgrade.rake +3 -1
- metadata +47 -15
- data/lib/jsonapi/resource_id_tree.rb +0 -112
data/lib/jsonapi/relationship.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module JSONAPI
|
2
4
|
class Relationship
|
3
5
|
attr_reader :acts_as_set, :foreign_key, :options, :name,
|
4
|
-
:class_name, :polymorphic, :always_include_optional_linkage_data,
|
6
|
+
:class_name, :polymorphic, :always_include_optional_linkage_data, :exclude_linkage_data,
|
5
7
|
:parent_resource, :eager_load_on_include, :custom_methods,
|
6
|
-
:inverse_relationship, :allow_include, :use_related_resource_records_for_joins
|
8
|
+
:inverse_relationship, :allow_include, :hidden, :use_related_resource_records_for_joins
|
7
9
|
|
8
10
|
attr_writer :allow_include
|
9
11
|
|
@@ -15,7 +17,7 @@ module JSONAPI
|
|
15
17
|
@acts_as_set = options.fetch(:acts_as_set, false) == true
|
16
18
|
@foreign_key = options[:foreign_key] ? options[:foreign_key].to_sym : nil
|
17
19
|
@parent_resource = options[:parent_resource]
|
18
|
-
@relation_name = options
|
20
|
+
@relation_name = options[:relation_name]
|
19
21
|
@polymorphic = options.fetch(:polymorphic, false) == true
|
20
22
|
@polymorphic_types = options[:polymorphic_types]
|
21
23
|
if options[:polymorphic_relations]
|
@@ -28,15 +30,19 @@ module JSONAPI
|
|
28
30
|
else
|
29
31
|
JSONAPI.configuration.use_related_resource_records_for_joins
|
30
32
|
end
|
31
|
-
|
33
|
+
|
32
34
|
@use_related_resource_records_for_joins = options.fetch(:use_related_resource_records_for_joins,
|
33
35
|
use_related_resource_records_for_joins_default) == true
|
34
36
|
|
37
|
+
@hidden = options.fetch(:hidden, false) == true
|
38
|
+
|
39
|
+
@exclude_linkage_data = options[:exclude_linkage_data]
|
35
40
|
@always_include_optional_linkage_data = options.fetch(:always_include_optional_linkage_data, false) == true
|
36
|
-
@eager_load_on_include = options.fetch(:eager_load_on_include,
|
41
|
+
@eager_load_on_include = options.fetch(:eager_load_on_include, true) == true
|
37
42
|
@allow_include = options[:allow_include]
|
38
43
|
@class_name = nil
|
39
|
-
|
44
|
+
|
45
|
+
@inverse_relationship = options[:inverse_relationship]&.to_sym
|
40
46
|
|
41
47
|
@_routed = false
|
42
48
|
@_warned_missing_route = false
|
@@ -66,12 +72,26 @@ module JSONAPI
|
|
66
72
|
# :nocov:
|
67
73
|
end
|
68
74
|
|
75
|
+
def inverse_relationship
|
76
|
+
unless @inverse_relationship
|
77
|
+
@inverse_relationship ||= if resource_klass._relationship(@parent_resource._type.to_s.singularize).present?
|
78
|
+
@parent_resource._type.to_s.singularize.to_sym
|
79
|
+
elsif resource_klass._relationship(@parent_resource._type).present?
|
80
|
+
@parent_resource._type.to_sym
|
81
|
+
else
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
@inverse_relationship
|
87
|
+
end
|
88
|
+
|
69
89
|
def self.polymorphic_types(name)
|
70
90
|
@poly_hash ||= {}.tap do |hash|
|
71
91
|
ObjectSpace.each_object do |klass|
|
72
92
|
next unless Module === klass
|
73
93
|
if ActiveRecord::Base > klass
|
74
|
-
klass.reflect_on_all_associations(:has_many).select{|r| r.options[:as] }.each do |reflection|
|
94
|
+
klass.reflect_on_all_associations(:has_many).select { |r| r.options[:as] }.each do |reflection|
|
75
95
|
(hash[reflection.options[:as]] ||= []) << klass.name.underscore
|
76
96
|
end
|
77
97
|
end
|
@@ -82,7 +102,7 @@ module JSONAPI
|
|
82
102
|
|
83
103
|
def resource_types
|
84
104
|
if polymorphic? && belongs_to?
|
85
|
-
@polymorphic_types ||= self.class.polymorphic_types(
|
105
|
+
@polymorphic_types ||= self.class.polymorphic_types(_relation_name).collect { |t| t.pluralize }
|
86
106
|
else
|
87
107
|
[resource_klass._type.to_s.pluralize]
|
88
108
|
end
|
@@ -93,15 +113,15 @@ module JSONAPI
|
|
93
113
|
end
|
94
114
|
|
95
115
|
def relation_name(options)
|
96
|
-
case
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
116
|
+
case _relation_name
|
117
|
+
when Symbol
|
118
|
+
# :nocov:
|
119
|
+
_relation_name
|
120
|
+
# :nocov:
|
121
|
+
when String
|
122
|
+
_relation_name.to_sym
|
123
|
+
when Proc
|
124
|
+
_relation_name.call(options)
|
105
125
|
end
|
106
126
|
end
|
107
127
|
|
@@ -117,14 +137,14 @@ module JSONAPI
|
|
117
137
|
|
118
138
|
def exclude_links(exclude)
|
119
139
|
case exclude
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
140
|
+
when :default, "default"
|
141
|
+
@_exclude_links = [:self, :related]
|
142
|
+
when :none, "none"
|
143
|
+
@_exclude_links = []
|
144
|
+
when Array
|
145
|
+
@_exclude_links = exclude.collect { |link| link.to_sym }
|
146
|
+
else
|
147
|
+
fail "Invalid exclude_links"
|
128
148
|
end
|
129
149
|
end
|
130
150
|
|
@@ -136,6 +156,10 @@ module JSONAPI
|
|
136
156
|
_exclude_links.include?(link.to_sym)
|
137
157
|
end
|
138
158
|
|
159
|
+
def _relation_name
|
160
|
+
@relation_name || @name
|
161
|
+
end
|
162
|
+
|
139
163
|
class ToOne < Relationship
|
140
164
|
attr_reader :foreign_key_on
|
141
165
|
|
@@ -144,9 +168,16 @@ module JSONAPI
|
|
144
168
|
@class_name = options.fetch(:class_name, name.to_s.camelize)
|
145
169
|
@foreign_key ||= "#{name}_id".to_sym
|
146
170
|
@foreign_key_on = options.fetch(:foreign_key_on, :self)
|
147
|
-
if parent_resource
|
148
|
-
|
171
|
+
# if parent_resource
|
172
|
+
# @inverse_relationship = options.fetch(:inverse_relationship, parent_resource._type)
|
173
|
+
# end
|
174
|
+
|
175
|
+
if options.fetch(:create_implicit_polymorphic_type_relationships, true) == true && polymorphic?
|
176
|
+
# Setup the implicit relationships for the polymorphic types and exclude linkage data
|
177
|
+
setup_implicit_relationships_for_polymorphic_types
|
149
178
|
end
|
179
|
+
|
180
|
+
@polymorphic_type_relationship_for = options[:polymorphic_type_relationship_for]
|
150
181
|
end
|
151
182
|
|
152
183
|
def to_s
|
@@ -161,11 +192,30 @@ module JSONAPI
|
|
161
192
|
# :nocov:
|
162
193
|
end
|
163
194
|
|
195
|
+
def hidden?
|
196
|
+
@hidden || @polymorphic_type_relationship_for.present?
|
197
|
+
end
|
198
|
+
|
164
199
|
def polymorphic_type
|
165
200
|
"#{name}_type" if polymorphic?
|
166
201
|
end
|
167
202
|
|
203
|
+
def setup_implicit_relationships_for_polymorphic_types(exclude_linkage_data: true)
|
204
|
+
types = self.class.polymorphic_types(_relation_name)
|
205
|
+
unless types.present?
|
206
|
+
warn "No polymorphic types found for #{parent_resource.name} #{_relation_name}"
|
207
|
+
return
|
208
|
+
end
|
209
|
+
|
210
|
+
types.each do |type|
|
211
|
+
parent_resource.has_one(type.to_s.underscore.singularize,
|
212
|
+
exclude_linkage_data: exclude_linkage_data,
|
213
|
+
polymorphic_type_relationship_for: name)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
168
217
|
def include_optional_linkage_data?
|
218
|
+
return false if @exclude_linkage_data
|
169
219
|
@always_include_optional_linkage_data || JSONAPI::configuration.always_include_to_one_linkage_data
|
170
220
|
end
|
171
221
|
|
@@ -176,10 +226,10 @@ module JSONAPI
|
|
176
226
|
@allow_include
|
177
227
|
end
|
178
228
|
|
179
|
-
if !!strategy == strategy #check for boolean
|
229
|
+
if !!strategy == strategy # check for boolean
|
180
230
|
return strategy
|
181
231
|
elsif strategy.is_a?(Symbol) || strategy.is_a?(String)
|
182
|
-
|
232
|
+
parent_resource_klass.send(strategy, context)
|
183
233
|
else
|
184
234
|
strategy.call(context)
|
185
235
|
end
|
@@ -194,17 +244,21 @@ module JSONAPI
|
|
194
244
|
@class_name = options.fetch(:class_name, name.to_s.camelize.singularize)
|
195
245
|
@foreign_key ||= "#{name.to_s.singularize}_ids".to_sym
|
196
246
|
@reflect = options.fetch(:reflect, true) == true
|
197
|
-
if parent_resource
|
198
|
-
|
199
|
-
end
|
247
|
+
# if parent_resource
|
248
|
+
# @inverse_relationship = options.fetch(:inverse_relationship, parent_resource._type.to_s.singularize.to_sym)
|
249
|
+
# end
|
200
250
|
end
|
201
251
|
|
202
252
|
def to_s
|
203
253
|
# :nocov: useful for debugging
|
204
|
-
"#{
|
254
|
+
"#{parent_resource_klass}.#{name}(ToMany)"
|
205
255
|
# :nocov:
|
206
256
|
end
|
207
257
|
|
258
|
+
def hidden?
|
259
|
+
@hidden
|
260
|
+
end
|
261
|
+
|
208
262
|
def include_optional_linkage_data?
|
209
263
|
# :nocov:
|
210
264
|
@always_include_optional_linkage_data || JSONAPI::configuration.always_include_to_many_linkage_data
|
@@ -218,10 +272,10 @@ module JSONAPI
|
|
218
272
|
@allow_include
|
219
273
|
end
|
220
274
|
|
221
|
-
if !!strategy == strategy #check for boolean
|
275
|
+
if !!strategy == strategy # check for boolean
|
222
276
|
return strategy
|
223
277
|
elsif strategy.is_a?(Symbol) || strategy.is_a?(String)
|
224
|
-
|
278
|
+
parent_resource_klass.send(strategy, context)
|
225
279
|
else
|
226
280
|
strategy.call(context)
|
227
281
|
end
|