jsonapi-resources 0.9.7 → 0.9.12

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3fc3aa84a3eee153f95a97c3d982e6fef51146998c0860ed4986f3c3911eb5c4
4
- data.tar.gz: c75e87dad876b378b4aef634c7103b6399b171b8392831b1a0365146c82c02f9
3
+ metadata.gz: bfb7891ac7686be582e0831afd808f08504e492998968e704de2086c1656e9af
4
+ data.tar.gz: edeb27a90bec0a6fc79f67e0311cdf7e588fdcf347426489c21d94bcd40a3f28
5
5
  SHA512:
6
- metadata.gz: a35bf550f5cdd014236b4ec680526bc1041a024644ba83a036e1d57c2c7e837456f713ad7f3f4bca95bacf7cc50bc7588fcfdf3550c96eb3802bf086a48dac43
7
- data.tar.gz: b322f9b3d22e6a3667f4b938559c3cf73af93fc54ad18311b443acafce36594cac7e2c8166c3b204e9ef50b07cb39f17b39edcbfa342d7a41434b359e7c9bd35
6
+ metadata.gz: 645534a3b1811e939fb6e36098e7624072793b59a39eecc99b05743ff77e91289ca6b35441c614220833049b689f8bcf7b6b6fb9fb1f09190b239b706b3d2da7
7
+ data.tar.gz: 7b562179f5f6ab17179c71208838fccaa1703d6c88eb99356075daa255a57242f59972e5ba0118740d4d80f7bc5706f2f87b4e99b0840cca32d00b19056f5712
@@ -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
@@ -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
- :routes
7
+ :engine_mount_point,
8
+ :url_helpers
9
+
10
+ @@url_helper_methods = {}
7
11
 
8
12
  def initialize(config = {})
9
- @base_url = config[:base_url]
13
+ @base_url = config[:base_url]
10
14
  @primary_resource_klass = config[:primary_resource_klass]
11
- @engine = build_engine
12
-
13
- if engine?
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
- # ToDo: Use NaiveCache for values. For this we need to not return nils and create composite keys which work
20
- # as efficient cache lookups. This could be an array of the [source.identifier, relationship] since the
21
- # ResourceIdentity will compare equality correctly
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
- @primary_resources_url_cached ||= "#{ base_url }#{ primary_resources_path }"
30
- rescue NoMethodError
31
- warn "primary_resources_url for #{@primary_resource_klass} could not be generated" if JSONAPI.configuration.warn_on_missing_routes
30
+ if @primary_resource_klass._routed
31
+ primary_resources_path = resources_path(primary_resource_klass)
32
+ @primary_resources_url_cached ||= "#{ base_url }#{ serialized_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
- "#{ primary_resources_url }?#{ query_params.to_query }"
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.parent_resource.singleton?
40
- url_helper_name = singleton_related_url_helper_name(relationship)
41
- url = call_url_helper(url_helper_name)
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
- url_helper_name = related_url_helper_name(relationship)
44
- url = call_url_helper(url_helper_name, source.id)
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.parent_resource.singleton?
56
- url_helper_name = singleton_relationship_self_url_helper_name(relationship)
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
- url_helper_name = relationship_self_url_helper_name(relationship)
60
- url = call_url_helper(url_helper_name, source.id)
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
- "#{ base_url }#{ resource_path(source) }"
71
- rescue NoMethodError
72
- warn "self_link for #{source.class} could not be generated" if JSONAPI.configuration.warn_on_missing_routes
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,96 +100,54 @@ module JSONAPI
88
100
  end
89
101
  end
90
102
 
91
- def call_url_helper(method, *args)
92
- routes.url_helpers.public_send(method, args)
93
- rescue NoMethodError => e
94
- raise e
103
+ def format_route(route)
104
+ route_formatter.format(route)
95
105
  end
96
106
 
97
- def path_from_resource_class(klass)
98
- url_helper_name = resources_url_helper_name_from_class(klass)
99
- call_url_helper(url_helper_name)
100
- end
107
+ def formatted_module_path_from_class(klass)
108
+ @_module_path_cache ||= {}
109
+ @_module_path_cache[klass] ||= begin
110
+ scopes = if @engine
111
+ module_scopes_from_class(klass)[1..-1]
112
+ else
113
+ module_scopes_from_class(klass)
114
+ end
101
115
 
102
- def resource_path(source)
103
- url_helper_name = resource_url_helper_name_from_source(source)
104
- if source.class.singleton?
105
- call_url_helper(url_helper_name)
106
- else
107
- call_url_helper(url_helper_name, source.id)
116
+ unless scopes.empty?
117
+ "/#{ scopes.map {|scope| format_route(scope.to_s.underscore)}.compact.join('/') }/"
118
+ else
119
+ "/"
120
+ end
108
121
  end
109
122
  end
110
123
 
111
- def primary_resources_path
112
- path_from_resource_class(primary_resource_klass)
113
- end
114
-
115
- def url_helper_name_from_parts(parts)
116
- (parts << "path").reject(&:blank?).join("_")
124
+ def module_scopes_from_class(klass)
125
+ klass.name.to_s.split("::")[0...-1]
117
126
  end
118
127
 
119
- def resources_path_parts_from_class(klass)
120
- if engine?
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]
128
+ def resources_path(source_klass)
129
+ formatted_module_path_from_class(source_klass) + format_route(source_klass._type.to_s)
129
130
  end
130
131
 
131
- def resources_url_helper_name_from_class(klass)
132
- url_helper_name_from_parts(resources_path_parts_from_class(klass))
133
- end
132
+ def resource_path(source)
133
+ url = "#{resources_path(source.class)}"
134
134
 
135
- def resource_path_parts_from_class(klass)
136
- if engine?
137
- scopes = module_scopes_from_class(klass)[1..-1]
138
- else
139
- scopes = module_scopes_from_class(klass)
135
+ unless source.class.singleton?
136
+ url = "#{url}/#{source.id}"
140
137
  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 << relationship.name
154
- url_helper_name_from_parts(relationship_parts)
155
- end
156
-
157
- def singleton_related_url_helper_name(relationship)
158
- relationship_parts = []
159
- relationship_parts << relationship.name
160
- relationship_parts += resource_path_parts_from_class(relationship.parent_resource)
161
- url_helper_name_from_parts(relationship_parts)
138
+ url
162
139
  end
163
140
 
164
- def relationship_self_url_helper_name(relationship)
165
- relationship_parts = resource_path_parts_from_class(relationship.parent_resource)
166
- relationship_parts << "relationships"
167
- relationship_parts << relationship.name
168
- url_helper_name_from_parts(relationship_parts)
141
+ def resource_url(source)
142
+ "#{ base_url }#{ serialized_engine_mount_point }#{ resource_path(source) }"
169
143
  end
170
144
 
171
- def singleton_relationship_self_url_helper_name(relationship)
172
- relationship_parts = []
173
- relationship_parts << "relationships"
174
- relationship_parts << relationship.name
175
- relationship_parts += resource_path_parts_from_class(relationship.parent_resource)
176
- url_helper_name_from_parts(relationship_parts)
145
+ def serialized_engine_mount_point
146
+ engine_mount_point == "/" ? "" : engine_mount_point
177
147
  end
178
148
 
179
- def module_scopes_from_class(klass)
180
- klass.name.to_s.split("::")[0...-1]
149
+ def route_for_relationship(relationship)
150
+ format_route(relationship.name)
181
151
  end
182
152
  end
183
153
  end
@@ -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, :none))
22
+ exclude_links(options.fetch(:exclude_links, JSONAPI.configuration.default_exclude_links))
19
23
  end
20
24
 
21
25
  alias_method :polymorphic?, :polymorphic
@@ -51,8 +55,14 @@ module JSONAPI
51
55
 
52
56
  def type_for_source(source)
53
57
  if polymorphic?
54
- resource = source.public_send(name)
55
- resource.class._type if resource
58
+ # try polymorphic type column before asking it from the resource record
59
+ if source._model.respond_to?(polymorphic_type)
60
+ model_type = source._model.send(polymorphic_type)
61
+ source.class.resource_for(model_type)._type if model_type
62
+ else
63
+ resource = source.public_send(name)
64
+ resource.class._type if resource
65
+ end
56
66
  else
57
67
  type
58
68
  end
@@ -291,7 +291,7 @@ module JSONAPI
291
291
  return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
292
292
  end
293
293
 
294
- verified_filter = relationship.resource_klass.verify_filters(filter_method => value)
294
+ verified_filter = relationship.resource_klass.verify_filters({ filter_method => value }, @context)
295
295
  @include_directives.merge_filter(relationship.name, verified_filter)
296
296
  else
297
297
  return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
@@ -314,7 +314,7 @@ module JSONAPI
314
314
 
315
315
  sorts = []
316
316
  begin
317
- raw = URI.unescape(sort_criteria)
317
+ raw = URI::DEFAULT_PARSER.unescape(sort_criteria)
318
318
  sorts += CSV.parse_line(raw)
319
319
  rescue CSV::MalformedCSVError
320
320
  fail JSONAPI::Exceptions::InvalidSortCriteria.new(format_key(@resource_klass._type), raw)
@@ -5,6 +5,9 @@ module JSONAPI
5
5
  class Resource
6
6
  include Callbacks
7
7
 
8
+ DEFAULT_ATTRIBUTE_OPTIONS = { format: :default }.freeze
9
+ MODULE_PATH_REGEXP = /::[^:]+\Z/.freeze
10
+
8
11
  attr_reader :context
9
12
 
10
13
  define_jsonapi_resources_callbacks :create,
@@ -372,7 +375,7 @@ module JSONAPI
372
375
 
373
376
  @reload_needed = true
374
377
  else
375
- @model.public_send(relationship.relation_name(context: @context)).destroy(key)
378
+ @model.public_send(relationship.relation_name(context: @context)).delete(key)
376
379
  end
377
380
 
378
381
  :completed
@@ -457,6 +460,9 @@ module JSONAPI
457
460
  end
458
461
 
459
462
  check_reserved_resource_name(subclass._type, subclass.name)
463
+
464
+ subclass._routed = false
465
+ subclass._warned_missing_route = false
460
466
  end
461
467
 
462
468
  def rebuild_relationships(relationships)
@@ -502,7 +508,7 @@ module JSONAPI
502
508
  end
503
509
  end
504
510
 
505
- attr_accessor :_attributes, :_relationships, :_type, :_model_hints
511
+ attr_accessor :_attributes, :_relationships, :_type, :_model_hints, :_routed, :_warned_missing_route
506
512
  attr_writer :_allowed_filters, :_paginator
507
513
 
508
514
  def create(context)
@@ -552,7 +558,7 @@ module JSONAPI
552
558
  end
553
559
 
554
560
  def default_attribute_options
555
- { format: :default }
561
+ DEFAULT_ATTRIBUTE_OPTIONS
556
562
  end
557
563
 
558
564
  def relationship(*attrs)
@@ -680,7 +686,7 @@ module JSONAPI
680
686
  include_directives = options[:include_directives]
681
687
  if include_directives
682
688
  model_includes = resolve_relationship_names_to_relations(self, include_directives.model_includes, options)
683
- records = records.includes(model_includes)
689
+ records = records.includes(model_includes) if model_includes.present?
684
690
  end
685
691
 
686
692
  records
@@ -1066,6 +1072,18 @@ module JSONAPI
1066
1072
  end
1067
1073
 
1068
1074
  def exclude_links(exclude)
1075
+ _resolve_exclude_links(exclude)
1076
+ end
1077
+
1078
+ def _exclude_links
1079
+ @_exclude_links ||= _resolve_exclude_links(JSONAPI.configuration.default_exclude_links)
1080
+ end
1081
+
1082
+ def exclude_link?(link)
1083
+ _exclude_links.include?(link.to_sym)
1084
+ end
1085
+
1086
+ def _resolve_exclude_links(exclude)
1069
1087
  case exclude
1070
1088
  when :default, "default"
1071
1089
  @_exclude_links = [:self]
@@ -1078,14 +1096,6 @@ module JSONAPI
1078
1096
  end
1079
1097
  end
1080
1098
 
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
1099
  def caching(val = true)
1090
1100
  @caching = val
1091
1101
  end
@@ -1126,7 +1136,7 @@ module JSONAPI
1126
1136
  if name == 'JSONAPI::Resource'
1127
1137
  ''
1128
1138
  else
1129
- name =~ /::[^:]+\Z/ ? ($`.freeze.gsub('::', '/') + '/').underscore : ''
1139
+ name =~ MODULE_PATH_REGEXP ? ($`.freeze.gsub('::', '/') + '/').underscore : ''
1130
1140
  end
1131
1141
  end
1132
1142
 
@@ -1344,7 +1354,8 @@ module JSONAPI
1344
1354
  rel_id = row[index+1]
1345
1355
  assoc_rels = res.preloaded_fragments[rel_name]
1346
1356
  if index == path.length - 1
1347
- assoc_rels[rel_id] = target_resources[klass.name].fetch(rel_id)
1357
+ association_res = target_resources[klass.name].fetch(rel_id, nil)
1358
+ assoc_rels[rel_id] = association_res if association_res
1348
1359
  else
1349
1360
  res = assoc_rels[rel_id]
1350
1361
  end
@@ -5,10 +5,10 @@ module JSONAPI
5
5
  ActionController::Rendering,
6
6
  ActionController::Renderers::All,
7
7
  ActionController::StrongParameters,
8
- ActionController::ForceSSL,
8
+ Gem::Requirement.new('< 6.1').satisfied_by?(ActionPack.gem_version) ? ActionController::ForceSSL : nil,
9
9
  ActionController::Instrumentation,
10
10
  JSONAPI::ActsAsResourceController
11
- ].freeze
11
+ ].compact.freeze
12
12
 
13
13
  MODULES.each do |mod|
14
14
  include mod
@@ -287,7 +287,6 @@ module JSONAPI
287
287
  include_linkage = ia && ia[:include]
288
288
  include_linked_children = ia && !ia[:include_related].empty?
289
289
 
290
- options = { filters: ia && ia[:include_filters] || {} }
291
290
  if field_set.include?(name)
292
291
  ro = relationship_object(source, relationship, include_linkage)
293
292
  hash[format_key(name)] = ro unless ro.blank?
@@ -300,6 +299,7 @@ module JSONAPI
300
299
  resources = if source.preloaded_fragments.has_key?(format_key(name))
301
300
  source.preloaded_fragments[format_key(name)].values
302
301
  else
302
+ options = { filters: ia && ia[:include_filters] || {} }
303
303
  [source.public_send(name, options)].flatten(1).compact
304
304
  end
305
305
  resources.each do |resource|
@@ -418,6 +418,7 @@ module JSONAPI
418
418
  [obj.type.underscore.pluralize, obj.id]
419
419
  end
420
420
  else
421
+ assoc = assoc.unscope(:includes) if assoc.is_a?(ActiveRecord::Relation)
421
422
  assoc.pluck(:type, :id).map do |type, id|
422
423
  [type.underscore.pluralize, id]
423
424
  end
@@ -467,16 +468,20 @@ module JSONAPI
467
468
 
468
469
  # Extracts the foreign key value for a to_one relationship.
469
470
  def foreign_key_value(source, relationship)
470
- related_resource_id = if source.preloaded_fragments.has_key?(format_key(relationship.name))
471
- source.preloaded_fragments[format_key(relationship.name)].values.first.try(:id)
472
- elsif source.respond_to?("#{relationship.name}_id")
473
- # If you have direct access to the underlying id, you don't have to load the relationship
474
- # which can save quite a lot of time when loading a lot of data.
475
- # This does not apply to e.g. has_one :through relationships.
476
- source.public_send("#{relationship.name}_id")
477
- else
478
- source.public_send(relationship.name).try(:id)
479
- end
471
+ # If you have changed the key_name, don't even try to look at `"#{relationship.name}_id"`
472
+ # just load the association and call the custom key_name
473
+ foreign_key_type_changed = relationship.options[:foreign_key_type_changed] || false
474
+ related_resource_id =
475
+ if source.preloaded_fragments.has_key?(format_key(relationship.name))
476
+ source.preloaded_fragments[format_key(relationship.name)].values.first.try(:id)
477
+ elsif !foreign_key_type_changed && source.respond_to?("#{relationship.name}_id")
478
+ # If you have direct access to the underlying id, you don't have to load the relationship
479
+ # which can save quite a lot of time when loading a lot of data.
480
+ # This does not apply to e.g. has_one :through relationships.
481
+ source.public_send("#{relationship.name}_id")
482
+ else
483
+ source.public_send(relationship.name).try(:id)
484
+ end
480
485
  return nil unless related_resource_id
481
486
  @id_formatter.format(related_resource_id)
482
487
  end
@@ -538,6 +543,8 @@ module JSONAPI
538
543
  LinkBuilder.new(
539
544
  base_url: options.fetch(:base_url, ''),
540
545
  primary_resource_klass: primary_resource_klass,
546
+ route_formatter: options.fetch(:route_formatter, JSONAPI.configuration.route_formatter),
547
+ url_helpers: options.fetch(:url_helpers, options[:controller]),
541
548
  )
542
549
  end
543
550
  end
@@ -1,5 +1,5 @@
1
1
  module JSONAPI
2
2
  module Resources
3
- VERSION = '0.9.7'
3
+ VERSION = '0.9.12'
4
4
  end
5
5
  end
@@ -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?
@@ -235,7 +241,7 @@ module ActionDispatch
235
241
  match formatted_relationship_name, controller: options[:controller],
236
242
  relationship: relationship.name, source: resource_type_with_module_prefix(source._type),
237
243
  action: 'get_related_resource', via: [:get],
238
- as: relationship_name
244
+ as: "related/#{relationship_name}"
239
245
  end
240
246
 
241
247
  def jsonapi_related_resources(*relationship)
@@ -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
@@ -253,7 +261,7 @@ module ActionDispatch
253
261
  controller: options[:controller],
254
262
  relationship: relationship.name, source: resource_type_with_module_prefix(source._type),
255
263
  action: 'get_related_resources', via: [:get],
256
- as: relationship_name
264
+ as: "related/#{relationship_name}"
257
265
  end
258
266
 
259
267
  protected
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.7
4
+ version: 0.9.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Gebhardt
@@ -9,22 +9,22 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-05-18 00:00:00.000000000 Z
12
+ date: 2021-02-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
18
+ - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: '1.5'
20
+ version: '0'
21
21
  type: :development
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - "~>"
25
+ - - ">="
26
26
  - !ruby/object:Gem::Version
27
- version: '1.5'
27
+ version: '0'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rake
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -123,6 +123,20 @@ dependencies:
123
123
  - - ">="
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: memory_profiler
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
126
140
  - !ruby/object:Gem::Dependency
127
141
  name: activerecord
128
142
  requirement: !ruby/object:Gem::Requirement
@@ -230,8 +244,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
230
244
  - !ruby/object:Gem::Version
231
245
  version: '0'
232
246
  requirements: []
233
- rubyforge_project:
234
- rubygems_version: 2.7.6
247
+ rubygems_version: 3.0.3
235
248
  signing_key:
236
249
  specification_version: 4
237
250
  summary: Easily support JSON API in Rails.