jsonapi-resources 0.9.8 → 0.9.9
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/lib/jsonapi/acts_as_resource_controller.rb +2 -1
- data/lib/jsonapi/configuration.rb +10 -1
- data/lib/jsonapi/link_builder.rb +76 -115
- data/lib/jsonapi/relationship.rb +5 -1
- data/lib/jsonapi/resource.rb +16 -9
- data/lib/jsonapi/resource_serializer.rb +2 -0
- data/lib/jsonapi/resources/version.rb +1 -1
- data/lib/jsonapi/routing_ext.rb +8 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4eea7d8efe26fb352cbe612525f39300935a37aae5a7aefed2dbd85ae6c5d4f4
|
4
|
+
data.tar.gz: 34c5c45acc815e60e4c8eefff863cb52c12b5ec1ef007685305e6d7f5d016c96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a59f2ba8abc7d5abd77dd210af2f132eb0631f8133c7b23bf595158cbf9cc09d0fc275740ca0b857dee172f02851f6f40b60c6584b5ec8b47f59b5b50bc09d44
|
7
|
+
data.tar.gz: df41e80df849d966a0a2dd86fa1b5f35133103568297ab4ac38710babca3eb41d3a289acce994ece2d51d98995813cd6b50bc1b1c86ffea9994ef777b3d53da4
|
@@ -125,7 +125,8 @@ module JSONAPI
|
|
125
125
|
base_url: base_url,
|
126
126
|
key_formatter: key_formatter,
|
127
127
|
route_formatter: route_formatter,
|
128
|
-
serialization_options: serialization_options
|
128
|
+
serialization_options: serialization_options,
|
129
|
+
controller: self
|
129
130
|
)
|
130
131
|
@resource_serializer
|
131
132
|
end
|
@@ -33,7 +33,8 @@ module JSONAPI
|
|
33
33
|
:resource_cache,
|
34
34
|
:default_resource_cache_field,
|
35
35
|
:resource_cache_digest_function,
|
36
|
-
:resource_cache_usage_report_function
|
36
|
+
:resource_cache_usage_report_function,
|
37
|
+
:default_exclude_links
|
37
38
|
|
38
39
|
def initialize
|
39
40
|
#:underscored_key, :camelized_key, :dasherized_key, or custom
|
@@ -134,6 +135,12 @@ module JSONAPI
|
|
134
135
|
# Optionally provide a callable which JSONAPI will call with information about cache
|
135
136
|
# performance. Should accept three arguments: resource name, hits count, misses count.
|
136
137
|
self.resource_cache_usage_report_function = nil
|
138
|
+
|
139
|
+
# Global configuration for links exclusion
|
140
|
+
# Controls whether to generate links like `self`, `related` with all the resources
|
141
|
+
# and relationships. Accepts either `:default`, `:none`, or array containing the
|
142
|
+
# specific default links to exclude, which may be `:self` and `:related`.
|
143
|
+
self.default_exclude_links = :none
|
137
144
|
end
|
138
145
|
|
139
146
|
def cache_formatters=(bool)
|
@@ -249,6 +256,8 @@ module JSONAPI
|
|
249
256
|
attr_writer :resource_cache_digest_function
|
250
257
|
|
251
258
|
attr_writer :resource_cache_usage_report_function
|
259
|
+
|
260
|
+
attr_writer :default_exclude_links
|
252
261
|
end
|
253
262
|
|
254
263
|
class << self
|
data/lib/jsonapi/link_builder.rb
CHANGED
@@ -2,23 +2,24 @@ module JSONAPI
|
|
2
2
|
class LinkBuilder
|
3
3
|
attr_reader :base_url,
|
4
4
|
:primary_resource_klass,
|
5
|
+
:route_formatter,
|
5
6
|
:engine,
|
6
|
-
:
|
7
|
+
:engine_mount_point,
|
8
|
+
:url_helpers
|
9
|
+
|
10
|
+
@@url_helper_methods = {}
|
7
11
|
|
8
12
|
def initialize(config = {})
|
9
|
-
@base_url
|
13
|
+
@base_url = config[:base_url]
|
10
14
|
@primary_resource_klass = config[:primary_resource_klass]
|
11
|
-
@
|
12
|
-
|
13
|
-
|
14
|
-
@routes = @engine.routes
|
15
|
-
else
|
16
|
-
@routes = Rails.application.routes
|
17
|
-
end
|
15
|
+
@route_formatter = config[:route_formatter]
|
16
|
+
@engine = build_engine
|
17
|
+
@engine_mount_point = @engine ? @engine.routes.find_script_name({}) : ""
|
18
18
|
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
19
|
+
# url_helpers may be either a controller which has the route helper methods, or the application router's
|
20
|
+
# url helpers module, `Rails.application.routes.url_helpers`. Because the method no longer behaves as a
|
21
|
+
# singleton, and it's expensive to generate the module, the controller is preferred.
|
22
|
+
@url_helpers = config[:url_helpers]
|
22
23
|
end
|
23
24
|
|
24
25
|
def engine?
|
@@ -26,50 +27,60 @@ module JSONAPI
|
|
26
27
|
end
|
27
28
|
|
28
29
|
def primary_resources_url
|
29
|
-
@
|
30
|
-
|
31
|
-
|
30
|
+
if @primary_resource_klass._routed
|
31
|
+
primary_resources_path = resources_path(primary_resource_klass)
|
32
|
+
@primary_resources_url_cached ||= "#{ base_url }#{ engine_mount_point }#{ primary_resources_path }"
|
33
|
+
else
|
34
|
+
if JSONAPI.configuration.warn_on_missing_routes && !@primary_resource_klass._warned_missing_route
|
35
|
+
warn "primary_resources_url for #{@primary_resource_klass} could not be generated"
|
36
|
+
@primary_resource_klass._warned_missing_route = true
|
37
|
+
end
|
38
|
+
nil
|
39
|
+
end
|
32
40
|
end
|
33
41
|
|
34
42
|
def query_link(query_params)
|
35
|
-
|
43
|
+
url = primary_resources_url
|
44
|
+
return url if url.nil?
|
45
|
+
"#{ url }?#{ query_params.to_query }"
|
36
46
|
end
|
37
47
|
|
38
48
|
def relationships_related_link(source, relationship, query_params = {})
|
39
|
-
if relationship.
|
40
|
-
|
41
|
-
url =
|
49
|
+
if relationship._routed
|
50
|
+
url = "#{ self_link(source) }/#{ route_for_relationship(relationship) }"
|
51
|
+
url = "#{ url }?#{ query_params.to_query }" if query_params.present?
|
52
|
+
url
|
42
53
|
else
|
43
|
-
|
44
|
-
|
54
|
+
if JSONAPI.configuration.warn_on_missing_routes && !relationship._warned_missing_route
|
55
|
+
warn "related_link for #{relationship} could not be generated"
|
56
|
+
relationship._warned_missing_route = true
|
57
|
+
end
|
58
|
+
nil
|
45
59
|
end
|
46
|
-
|
47
|
-
url = "#{ base_url }#{ url }"
|
48
|
-
url = "#{ url }?#{ query_params.to_query }" if query_params.present?
|
49
|
-
url
|
50
|
-
rescue NoMethodError
|
51
|
-
warn "related_link for #{relationship} could not be generated" if JSONAPI.configuration.warn_on_missing_routes
|
52
60
|
end
|
53
61
|
|
54
62
|
def relationships_self_link(source, relationship)
|
55
|
-
if relationship.
|
56
|
-
|
57
|
-
url = call_url_helper(url_helper_name)
|
63
|
+
if relationship._routed
|
64
|
+
"#{ self_link(source) }/relationships/#{ route_for_relationship(relationship) }"
|
58
65
|
else
|
59
|
-
|
60
|
-
|
66
|
+
if JSONAPI.configuration.warn_on_missing_routes && !relationship._warned_missing_route
|
67
|
+
warn "self_link for #{relationship} could not be generated"
|
68
|
+
relationship._warned_missing_route = true
|
69
|
+
end
|
70
|
+
nil
|
61
71
|
end
|
62
|
-
|
63
|
-
url = "#{ base_url }#{ url }"
|
64
|
-
url
|
65
|
-
rescue NoMethodError
|
66
|
-
warn "self_link for #{relationship} could not be generated" if JSONAPI.configuration.warn_on_missing_routes
|
67
72
|
end
|
68
73
|
|
69
74
|
def self_link(source)
|
70
|
-
|
71
|
-
|
72
|
-
|
75
|
+
if source.class._routed
|
76
|
+
resource_url(source)
|
77
|
+
else
|
78
|
+
if JSONAPI.configuration.warn_on_missing_routes && !source.class._warned_missing_route
|
79
|
+
warn "self_link for #{source.class} could not be generated"
|
80
|
+
source.class._warned_missing_route = true
|
81
|
+
end
|
82
|
+
nil
|
83
|
+
end
|
73
84
|
end
|
74
85
|
|
75
86
|
private
|
@@ -81,6 +92,7 @@ module JSONAPI
|
|
81
92
|
unless scopes.empty?
|
82
93
|
"#{ scopes.first.to_s.camelize }::Engine".safe_constantize
|
83
94
|
end
|
95
|
+
|
84
96
|
# :nocov:
|
85
97
|
rescue LoadError => _e
|
86
98
|
nil
|
@@ -88,98 +100,47 @@ module JSONAPI
|
|
88
100
|
end
|
89
101
|
end
|
90
102
|
|
91
|
-
def
|
92
|
-
|
93
|
-
rescue NoMethodError => e
|
94
|
-
raise e
|
103
|
+
def format_route(route)
|
104
|
+
route_formatter.format(route)
|
95
105
|
end
|
96
106
|
|
97
|
-
def
|
98
|
-
|
99
|
-
|
100
|
-
|
107
|
+
def formatted_module_path_from_class(klass)
|
108
|
+
scopes = if @engine
|
109
|
+
module_scopes_from_class(klass)[1..-1]
|
110
|
+
else
|
111
|
+
module_scopes_from_class(klass)
|
112
|
+
end
|
101
113
|
|
102
|
-
|
103
|
-
|
104
|
-
if source.class.singleton?
|
105
|
-
call_url_helper(url_helper_name)
|
114
|
+
unless scopes.empty?
|
115
|
+
"/#{ scopes.map {|scope| format_route(scope.to_s.underscore)}.compact.join('/') }/"
|
106
116
|
else
|
107
|
-
|
117
|
+
"/"
|
108
118
|
end
|
109
119
|
end
|
110
120
|
|
111
|
-
def
|
112
|
-
|
121
|
+
def module_scopes_from_class(klass)
|
122
|
+
klass.name.to_s.split("::")[0...-1]
|
113
123
|
end
|
114
124
|
|
115
|
-
def
|
116
|
-
(
|
125
|
+
def resources_path(source_klass)
|
126
|
+
formatted_module_path_from_class(source_klass) + format_route(source_klass._type.to_s)
|
117
127
|
end
|
118
128
|
|
119
|
-
def
|
120
|
-
|
121
|
-
scopes = module_scopes_from_class(klass)[1..-1]
|
122
|
-
else
|
123
|
-
scopes = module_scopes_from_class(klass)
|
124
|
-
end
|
125
|
-
|
126
|
-
base_path_name = scopes.map { |scope| scope.underscore }.join("_")
|
127
|
-
end_path_name = klass._type.to_s
|
128
|
-
[base_path_name, end_path_name]
|
129
|
-
end
|
130
|
-
|
131
|
-
def resources_url_helper_name_from_class(klass)
|
132
|
-
url_helper_name_from_parts(resources_path_parts_from_class(klass))
|
133
|
-
end
|
129
|
+
def resource_path(source)
|
130
|
+
url = "#{resources_path(source.class)}"
|
134
131
|
|
135
|
-
|
136
|
-
|
137
|
-
scopes = module_scopes_from_class(klass)[1..-1]
|
138
|
-
else
|
139
|
-
scopes = module_scopes_from_class(klass)
|
132
|
+
unless source.class.singleton?
|
133
|
+
url = "#{url}/#{source.id}"
|
140
134
|
end
|
141
|
-
|
142
|
-
base_path_name = scopes.map { |scope| scope.underscore }.join("_")
|
143
|
-
end_path_name = klass._type.to_s.singularize
|
144
|
-
[base_path_name, end_path_name]
|
145
|
-
end
|
146
|
-
|
147
|
-
def resource_url_helper_name_from_source(source)
|
148
|
-
url_helper_name_from_parts(resource_path_parts_from_class(source.class))
|
149
|
-
end
|
150
|
-
|
151
|
-
def related_url_helper_name(relationship)
|
152
|
-
relationship_parts = resource_path_parts_from_class(relationship.parent_resource)
|
153
|
-
relationship_parts << "related"
|
154
|
-
relationship_parts << relationship.name
|
155
|
-
url_helper_name_from_parts(relationship_parts)
|
156
|
-
end
|
157
|
-
|
158
|
-
def singleton_related_url_helper_name(relationship)
|
159
|
-
relationship_parts = []
|
160
|
-
relationship_parts << "related"
|
161
|
-
relationship_parts << relationship.name
|
162
|
-
relationship_parts += resource_path_parts_from_class(relationship.parent_resource)
|
163
|
-
url_helper_name_from_parts(relationship_parts)
|
164
|
-
end
|
165
|
-
|
166
|
-
def relationship_self_url_helper_name(relationship)
|
167
|
-
relationship_parts = resource_path_parts_from_class(relationship.parent_resource)
|
168
|
-
relationship_parts << "relationships"
|
169
|
-
relationship_parts << relationship.name
|
170
|
-
url_helper_name_from_parts(relationship_parts)
|
135
|
+
url
|
171
136
|
end
|
172
137
|
|
173
|
-
def
|
174
|
-
|
175
|
-
relationship_parts << "relationships"
|
176
|
-
relationship_parts << relationship.name
|
177
|
-
relationship_parts += resource_path_parts_from_class(relationship.parent_resource)
|
178
|
-
url_helper_name_from_parts(relationship_parts)
|
138
|
+
def resource_url(source)
|
139
|
+
"#{ base_url }#{ engine_mount_point }#{ resource_path(source) }"
|
179
140
|
end
|
180
141
|
|
181
|
-
def
|
182
|
-
|
142
|
+
def route_for_relationship(relationship)
|
143
|
+
format_route(relationship.name)
|
183
144
|
end
|
184
145
|
end
|
185
146
|
end
|
data/lib/jsonapi/relationship.rb
CHANGED
@@ -4,6 +4,8 @@ module JSONAPI
|
|
4
4
|
:class_name, :polymorphic, :always_include_linkage_data,
|
5
5
|
:parent_resource, :eager_load_on_include
|
6
6
|
|
7
|
+
attr_accessor :_routed, :_warned_missing_route
|
8
|
+
|
7
9
|
def initialize(name, options = {})
|
8
10
|
@name = name.to_s
|
9
11
|
@options = options
|
@@ -14,8 +16,10 @@ module JSONAPI
|
|
14
16
|
@polymorphic = options.fetch(:polymorphic, false) == true
|
15
17
|
@always_include_linkage_data = options.fetch(:always_include_linkage_data, false) == true
|
16
18
|
@eager_load_on_include = options.fetch(:eager_load_on_include, true) == true
|
19
|
+
@_routed = false
|
20
|
+
@_warned_missing_route = false
|
17
21
|
|
18
|
-
exclude_links(options.fetch(:exclude_links,
|
22
|
+
exclude_links(options.fetch(:exclude_links, JSONAPI.configuration.default_exclude_links))
|
19
23
|
end
|
20
24
|
|
21
25
|
alias_method :polymorphic?, :polymorphic
|
data/lib/jsonapi/resource.rb
CHANGED
@@ -457,6 +457,9 @@ module JSONAPI
|
|
457
457
|
end
|
458
458
|
|
459
459
|
check_reserved_resource_name(subclass._type, subclass.name)
|
460
|
+
|
461
|
+
subclass._routed = false
|
462
|
+
subclass._warned_missing_route = false
|
460
463
|
end
|
461
464
|
|
462
465
|
def rebuild_relationships(relationships)
|
@@ -502,7 +505,7 @@ module JSONAPI
|
|
502
505
|
end
|
503
506
|
end
|
504
507
|
|
505
|
-
attr_accessor :_attributes, :_relationships, :_type, :_model_hints
|
508
|
+
attr_accessor :_attributes, :_relationships, :_type, :_model_hints, :_routed, :_warned_missing_route
|
506
509
|
attr_writer :_allowed_filters, :_paginator
|
507
510
|
|
508
511
|
def create(context)
|
@@ -1066,6 +1069,18 @@ module JSONAPI
|
|
1066
1069
|
end
|
1067
1070
|
|
1068
1071
|
def exclude_links(exclude)
|
1072
|
+
_resolve_exclude_links(exclude)
|
1073
|
+
end
|
1074
|
+
|
1075
|
+
def _exclude_links
|
1076
|
+
@_exclude_links ||= _resolve_exclude_links(JSONAPI.configuration.default_exclude_links)
|
1077
|
+
end
|
1078
|
+
|
1079
|
+
def exclude_link?(link)
|
1080
|
+
_exclude_links.include?(link.to_sym)
|
1081
|
+
end
|
1082
|
+
|
1083
|
+
def _resolve_exclude_links(exclude)
|
1069
1084
|
case exclude
|
1070
1085
|
when :default, "default"
|
1071
1086
|
@_exclude_links = [:self]
|
@@ -1078,14 +1093,6 @@ module JSONAPI
|
|
1078
1093
|
end
|
1079
1094
|
end
|
1080
1095
|
|
1081
|
-
def _exclude_links
|
1082
|
-
@_exclude_links ||= []
|
1083
|
-
end
|
1084
|
-
|
1085
|
-
def exclude_link?(link)
|
1086
|
-
_exclude_links.include?(link.to_sym)
|
1087
|
-
end
|
1088
|
-
|
1089
1096
|
def caching(val = true)
|
1090
1097
|
@caching = val
|
1091
1098
|
end
|
@@ -539,6 +539,8 @@ module JSONAPI
|
|
539
539
|
LinkBuilder.new(
|
540
540
|
base_url: options.fetch(:base_url, ''),
|
541
541
|
primary_resource_klass: primary_resource_klass,
|
542
|
+
route_formatter: options.fetch(:route_formatter, JSONAPI.configuration.route_formatter),
|
543
|
+
url_helpers: options.fetch(:url_helpers, options[:controller]),
|
542
544
|
)
|
543
545
|
end
|
544
546
|
end
|
data/lib/jsonapi/routing_ext.rb
CHANGED
@@ -20,6 +20,8 @@ module ActionDispatch
|
|
20
20
|
@resource_type = resources.first
|
21
21
|
res = JSONAPI::Resource.resource_for(resource_type_with_module_prefix(@resource_type))
|
22
22
|
|
23
|
+
res._routed = true
|
24
|
+
|
23
25
|
unless res.singleton?
|
24
26
|
warn "Singleton routes created for non singleton resource #{res}. Links may not be generated correctly."
|
25
27
|
end
|
@@ -84,6 +86,8 @@ module ActionDispatch
|
|
84
86
|
@resource_type = resources.first
|
85
87
|
res = JSONAPI::Resource.resource_for(resource_type_with_module_prefix(@resource_type))
|
86
88
|
|
89
|
+
res._routed = true
|
90
|
+
|
87
91
|
if res.singleton?
|
88
92
|
warn "Singleton resource #{res} should use `jsonapi_resource` instead."
|
89
93
|
end
|
@@ -223,6 +227,8 @@ module ActionDispatch
|
|
223
227
|
relationship_name = relationship.first
|
224
228
|
relationship = source._relationships[relationship_name]
|
225
229
|
|
230
|
+
relationship._routed = true
|
231
|
+
|
226
232
|
formatted_relationship_name = format_route(relationship.name)
|
227
233
|
|
228
234
|
if relationship.polymorphic?
|
@@ -245,6 +251,8 @@ module ActionDispatch
|
|
245
251
|
relationship_name = relationship.first
|
246
252
|
relationship = source._relationships[relationship_name]
|
247
253
|
|
254
|
+
relationship._routed = true
|
255
|
+
|
248
256
|
formatted_relationship_name = format_route(relationship.name)
|
249
257
|
related_resource = JSONAPI::Resource.resource_for(resource_type_with_module_prefix(relationship.class_name.underscore))
|
250
258
|
options[:controller] ||= related_resource._type.to_s
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsonapi-resources
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Gebhardt
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-06-
|
12
|
+
date: 2019-06-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|