jsonapi-resources 0.9.0 → 0.10.6
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 +5 -5
- data/LICENSE.txt +1 -1
- data/README.md +34 -11
- data/lib/bug_report_templates/rails_5_latest.rb +125 -0
- data/lib/bug_report_templates/rails_5_master.rb +140 -0
- data/lib/jsonapi/active_relation/adapters/join_left_active_record_adapter.rb +27 -0
- data/lib/jsonapi/active_relation/join_manager.rb +303 -0
- data/lib/jsonapi/active_relation_resource.rb +884 -0
- data/lib/jsonapi/acts_as_resource_controller.rb +122 -105
- data/lib/jsonapi/basic_resource.rb +1162 -0
- data/lib/jsonapi/cached_response_fragment.rb +127 -0
- data/lib/jsonapi/compiled_json.rb +11 -1
- data/lib/jsonapi/configuration.rb +71 -8
- data/lib/jsonapi/error.rb +27 -0
- data/lib/jsonapi/error_codes.rb +2 -0
- data/lib/jsonapi/exceptions.rb +80 -50
- data/lib/jsonapi/formatter.rb +3 -3
- data/lib/jsonapi/include_directives.rb +18 -65
- data/lib/jsonapi/link_builder.rb +74 -80
- data/lib/jsonapi/operation.rb +16 -5
- data/lib/jsonapi/operation_result.rb +74 -16
- data/lib/jsonapi/path.rb +43 -0
- data/lib/jsonapi/path_segment.rb +76 -0
- data/lib/jsonapi/processor.rb +239 -111
- data/lib/jsonapi/relationship.rb +153 -15
- data/lib/jsonapi/request_parser.rb +430 -367
- data/lib/jsonapi/resource.rb +3 -1253
- data/lib/jsonapi/resource_controller_metal.rb +5 -2
- data/lib/jsonapi/resource_fragment.rb +47 -0
- data/lib/jsonapi/resource_id_tree.rb +112 -0
- data/lib/jsonapi/resource_identity.rb +42 -0
- data/lib/jsonapi/resource_serializer.rb +143 -285
- data/lib/jsonapi/resource_set.rb +176 -0
- data/lib/jsonapi/resources/railtie.rb +9 -0
- data/lib/jsonapi/resources/version.rb +1 -1
- data/lib/jsonapi/response_document.rb +105 -83
- data/lib/jsonapi/routing_ext.rb +48 -26
- data/lib/jsonapi-resources.rb +20 -4
- data/lib/tasks/check_upgrade.rake +52 -0
- metadata +50 -20
- data/lib/jsonapi/cached_resource_fragment.rb +0 -127
- data/lib/jsonapi/operation_dispatcher.rb +0 -88
- data/lib/jsonapi/operation_results.rb +0 -35
- data/lib/jsonapi/relationship_builder.rb +0 -167
data/lib/jsonapi/relationship.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
module JSONAPI
|
2
2
|
class Relationship
|
3
3
|
attr_reader :acts_as_set, :foreign_key, :options, :name,
|
4
|
-
:class_name, :polymorphic, :
|
5
|
-
:parent_resource, :eager_load_on_include
|
4
|
+
:class_name, :polymorphic, :always_include_optional_linkage_data,
|
5
|
+
:parent_resource, :eager_load_on_include, :custom_methods,
|
6
|
+
:inverse_relationship, :allow_include, :use_related_resource_records_for_joins
|
7
|
+
|
8
|
+
attr_writer :allow_include
|
9
|
+
|
10
|
+
attr_accessor :_routed, :_warned_missing_route
|
6
11
|
|
7
12
|
def initialize(name, options = {})
|
8
13
|
@name = name.to_s
|
@@ -12,22 +17,75 @@ module JSONAPI
|
|
12
17
|
@parent_resource = options[:parent_resource]
|
13
18
|
@relation_name = options.fetch(:relation_name, @name)
|
14
19
|
@polymorphic = options.fetch(:polymorphic, false) == true
|
15
|
-
@
|
16
|
-
|
20
|
+
@polymorphic_types = options[:polymorphic_types]
|
21
|
+
if options[:polymorphic_relations]
|
22
|
+
ActiveSupport::Deprecation.warn('Use polymorphic_types instead of polymorphic_relations')
|
23
|
+
@polymorphic_types ||= options[:polymorphic_relations]
|
24
|
+
end
|
25
|
+
|
26
|
+
use_related_resource_records_for_joins_default = if options[:relation_name]
|
27
|
+
false
|
28
|
+
else
|
29
|
+
JSONAPI.configuration.use_related_resource_records_for_joins
|
30
|
+
end
|
31
|
+
|
32
|
+
@use_related_resource_records_for_joins = options.fetch(:use_related_resource_records_for_joins,
|
33
|
+
use_related_resource_records_for_joins_default) == true
|
34
|
+
|
35
|
+
@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, false) == true
|
37
|
+
@allow_include = options[:allow_include]
|
38
|
+
@class_name = nil
|
39
|
+
@inverse_relationship = nil
|
40
|
+
|
41
|
+
@_routed = false
|
42
|
+
@_warned_missing_route = false
|
43
|
+
|
44
|
+
exclude_links(options.fetch(:exclude_links, JSONAPI.configuration.default_exclude_links))
|
45
|
+
|
46
|
+
# Custom methods are reserved for future use
|
47
|
+
@custom_methods = options.fetch(:custom_methods, {})
|
17
48
|
end
|
18
49
|
|
19
50
|
alias_method :polymorphic?, :polymorphic
|
51
|
+
alias_method :parent_resource_klass, :parent_resource
|
20
52
|
|
21
53
|
def primary_key
|
54
|
+
# :nocov:
|
22
55
|
@primary_key ||= resource_klass._primary_key
|
56
|
+
# :nocov:
|
23
57
|
end
|
24
58
|
|
25
59
|
def resource_klass
|
26
|
-
@resource_klass ||= @parent_resource.
|
60
|
+
@resource_klass ||= @parent_resource.resource_klass_for(@class_name)
|
27
61
|
end
|
28
62
|
|
29
63
|
def table_name
|
64
|
+
# :nocov:
|
30
65
|
@table_name ||= resource_klass._table_name
|
66
|
+
# :nocov:
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.polymorphic_types(name)
|
70
|
+
@poly_hash ||= {}.tap do |hash|
|
71
|
+
ObjectSpace.each_object do |klass|
|
72
|
+
next unless Module === klass
|
73
|
+
if ActiveRecord::Base > klass
|
74
|
+
klass.reflect_on_all_associations(:has_many).select{|r| r.options[:as] }.each do |reflection|
|
75
|
+
(hash[reflection.options[:as]] ||= []) << klass.name.underscore
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
@poly_hash[name.to_sym]
|
81
|
+
end
|
82
|
+
|
83
|
+
def resource_types
|
84
|
+
if polymorphic? && belongs_to?
|
85
|
+
@polymorphic_types ||= self.class.polymorphic_types(@relation_name).collect {|t| t.pluralize}
|
86
|
+
else
|
87
|
+
[resource_klass._type.to_s.pluralize]
|
88
|
+
end
|
31
89
|
end
|
32
90
|
|
33
91
|
def type
|
@@ -47,17 +105,35 @@ module JSONAPI
|
|
47
105
|
end
|
48
106
|
end
|
49
107
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
108
|
+
def belongs_to?
|
109
|
+
# :nocov:
|
110
|
+
false
|
111
|
+
# :nocov:
|
112
|
+
end
|
113
|
+
|
114
|
+
def readonly?
|
115
|
+
@options[:readonly]
|
116
|
+
end
|
117
|
+
|
118
|
+
def exclude_links(exclude)
|
119
|
+
case exclude
|
120
|
+
when :default, "default"
|
121
|
+
@_exclude_links = [:self, :related]
|
122
|
+
when :none, "none"
|
123
|
+
@_exclude_links = []
|
124
|
+
when Array
|
125
|
+
@_exclude_links = exclude.collect {|link| link.to_sym}
|
126
|
+
else
|
127
|
+
fail "Invalid exclude_links"
|
56
128
|
end
|
57
129
|
end
|
58
130
|
|
59
|
-
def
|
60
|
-
|
131
|
+
def _exclude_links
|
132
|
+
@_exclude_links ||= []
|
133
|
+
end
|
134
|
+
|
135
|
+
def exclude_link?(link)
|
136
|
+
_exclude_links.include?(link.to_sym)
|
61
137
|
end
|
62
138
|
|
63
139
|
class ToOne < Relationship
|
@@ -68,27 +144,89 @@ module JSONAPI
|
|
68
144
|
@class_name = options.fetch(:class_name, name.to_s.camelize)
|
69
145
|
@foreign_key ||= "#{name}_id".to_sym
|
70
146
|
@foreign_key_on = options.fetch(:foreign_key_on, :self)
|
147
|
+
if parent_resource
|
148
|
+
@inverse_relationship = options.fetch(:inverse_relationship, parent_resource._type)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def to_s
|
153
|
+
# :nocov: useful for debugging
|
154
|
+
"#{parent_resource}.#{name}(#{belongs_to? ? 'BelongsToOne' : 'ToOne'})"
|
155
|
+
# :nocov:
|
71
156
|
end
|
72
157
|
|
73
158
|
def belongs_to?
|
159
|
+
# :nocov:
|
74
160
|
foreign_key_on == :self
|
161
|
+
# :nocov:
|
75
162
|
end
|
76
163
|
|
77
164
|
def polymorphic_type
|
78
165
|
"#{name}_type" if polymorphic?
|
79
166
|
end
|
167
|
+
|
168
|
+
def include_optional_linkage_data?
|
169
|
+
@always_include_optional_linkage_data || JSONAPI::configuration.always_include_to_one_linkage_data
|
170
|
+
end
|
171
|
+
|
172
|
+
def allow_include?(context = nil)
|
173
|
+
strategy = if @allow_include.nil?
|
174
|
+
JSONAPI.configuration.default_allow_include_to_one
|
175
|
+
else
|
176
|
+
@allow_include
|
177
|
+
end
|
178
|
+
|
179
|
+
if !!strategy == strategy #check for boolean
|
180
|
+
return strategy
|
181
|
+
elsif strategy.is_a?(Symbol) || strategy.is_a?(String)
|
182
|
+
parent_resource.send(strategy, context)
|
183
|
+
else
|
184
|
+
strategy.call(context)
|
185
|
+
end
|
186
|
+
end
|
80
187
|
end
|
81
188
|
|
82
189
|
class ToMany < Relationship
|
83
|
-
attr_reader :reflect
|
190
|
+
attr_reader :reflect
|
84
191
|
|
85
192
|
def initialize(name, options = {})
|
86
193
|
super
|
87
194
|
@class_name = options.fetch(:class_name, name.to_s.camelize.singularize)
|
88
195
|
@foreign_key ||= "#{name.to_s.singularize}_ids".to_sym
|
89
196
|
@reflect = options.fetch(:reflect, true) == true
|
90
|
-
|
197
|
+
if parent_resource
|
198
|
+
@inverse_relationship = options.fetch(:inverse_relationship, parent_resource._type.to_s.singularize.to_sym)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def to_s
|
203
|
+
# :nocov: useful for debugging
|
204
|
+
"#{parent_resource}.#{name}(ToMany)"
|
205
|
+
# :nocov:
|
206
|
+
end
|
207
|
+
|
208
|
+
def include_optional_linkage_data?
|
209
|
+
# :nocov:
|
210
|
+
@always_include_optional_linkage_data || JSONAPI::configuration.always_include_to_many_linkage_data
|
211
|
+
# :nocov:
|
91
212
|
end
|
213
|
+
|
214
|
+
def allow_include?(context = nil)
|
215
|
+
strategy = if @allow_include.nil?
|
216
|
+
JSONAPI.configuration.default_allow_include_to_many
|
217
|
+
else
|
218
|
+
@allow_include
|
219
|
+
end
|
220
|
+
|
221
|
+
if !!strategy == strategy #check for boolean
|
222
|
+
return strategy
|
223
|
+
elsif strategy.is_a?(Symbol) || strategy.is_a?(String)
|
224
|
+
parent_resource.send(strategy, context)
|
225
|
+
else
|
226
|
+
strategy.call(context)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
92
230
|
end
|
93
231
|
end
|
94
232
|
end
|