sanger-jsonapi-resources 0.1.1 → 0.2.0

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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +35 -12
  4. data/lib/bug_report_templates/rails_5_latest.rb +125 -0
  5. data/lib/bug_report_templates/rails_5_master.rb +140 -0
  6. data/lib/jsonapi/active_relation/adapters/join_left_active_record_adapter.rb +26 -0
  7. data/lib/jsonapi/active_relation/join_manager.rb +297 -0
  8. data/lib/jsonapi/active_relation_resource.rb +898 -0
  9. data/lib/jsonapi/acts_as_resource_controller.rb +130 -113
  10. data/lib/jsonapi/basic_resource.rb +1164 -0
  11. data/lib/jsonapi/cached_response_fragment.rb +129 -0
  12. data/lib/jsonapi/callbacks.rb +2 -0
  13. data/lib/jsonapi/compatibility_helper.rb +29 -0
  14. data/lib/jsonapi/compiled_json.rb +13 -1
  15. data/lib/jsonapi/configuration.rb +88 -21
  16. data/lib/jsonapi/error.rb +29 -0
  17. data/lib/jsonapi/error_codes.rb +4 -0
  18. data/lib/jsonapi/exceptions.rb +82 -50
  19. data/lib/jsonapi/formatter.rb +5 -3
  20. data/lib/jsonapi/include_directives.rb +22 -67
  21. data/lib/jsonapi/link_builder.rb +76 -80
  22. data/lib/jsonapi/mime_types.rb +6 -10
  23. data/lib/jsonapi/naive_cache.rb +2 -0
  24. data/lib/jsonapi/operation.rb +18 -5
  25. data/lib/jsonapi/operation_result.rb +76 -16
  26. data/lib/jsonapi/paginator.rb +2 -0
  27. data/lib/jsonapi/path.rb +45 -0
  28. data/lib/jsonapi/path_segment.rb +78 -0
  29. data/lib/jsonapi/processor.rb +193 -115
  30. data/lib/jsonapi/relationship.rb +145 -14
  31. data/lib/jsonapi/request.rb +734 -0
  32. data/lib/jsonapi/resource.rb +3 -1251
  33. data/lib/jsonapi/resource_controller.rb +2 -0
  34. data/lib/jsonapi/resource_controller_metal.rb +7 -1
  35. data/lib/jsonapi/resource_fragment.rb +56 -0
  36. data/lib/jsonapi/resource_identity.rb +44 -0
  37. data/lib/jsonapi/resource_serializer.rb +158 -284
  38. data/lib/jsonapi/resource_set.rb +196 -0
  39. data/lib/jsonapi/resource_tree.rb +236 -0
  40. data/lib/jsonapi/resources/railtie.rb +9 -0
  41. data/lib/jsonapi/resources/version.rb +1 -1
  42. data/lib/jsonapi/response_document.rb +107 -83
  43. data/lib/jsonapi/routing_ext.rb +50 -26
  44. data/lib/jsonapi-resources.rb +23 -5
  45. data/lib/tasks/check_upgrade.rake +52 -0
  46. metadata +43 -31
  47. data/lib/jsonapi/cached_resource_fragment.rb +0 -127
  48. data/lib/jsonapi/operation_dispatcher.rb +0 -88
  49. data/lib/jsonapi/operation_results.rb +0 -35
  50. data/lib/jsonapi/relationship_builder.rb +0 -167
  51. data/lib/jsonapi/request_parser.rb +0 -678
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionDispatch
2
4
  module Routing
3
5
  class Mapper
@@ -18,7 +20,13 @@ module ActionDispatch
18
20
 
19
21
  def jsonapi_resource(*resources, &_block)
20
22
  @resource_type = resources.first
21
- res = JSONAPI::Resource.resource_for(resource_type_with_module_prefix(@resource_type))
23
+ res = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix(@resource_type))
24
+
25
+ res._routed = true
26
+
27
+ unless res.singleton?
28
+ warn "Singleton routes created for non singleton resource #{res}. Links may not be generated correctly."
29
+ end
22
30
 
23
31
  options = resources.extract_options!.dup
24
32
  options[:controller] ||= @resource_type
@@ -33,8 +41,8 @@ module ActionDispatch
33
41
  end
34
42
 
35
43
  if res._immutable
36
- options[:except] << :create unless options[:except].include?(:create) || options[:except].include?('create')
37
- options[:except] << :update unless options[:except].include?(:update) || options[:except].include?('update')
44
+ options[:except] << :create unless options[:except].include?(:create) || options[:except].include?('create')
45
+ options[:except] << :update unless options[:except].include?(:update) || options[:except].include?('update')
38
46
  options[:except] << :destroy unless options[:except].include?(:destroy) || options[:except].include?('destroy')
39
47
  end
40
48
 
@@ -64,7 +72,7 @@ module ActionDispatch
64
72
  end
65
73
 
66
74
  def jsonapi_relationships(options = {})
67
- res = JSONAPI::Resource.resource_for(resource_type_with_module_prefix(@resource_type))
75
+ res = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix(@resource_type))
68
76
  res._relationships.each do |relationship_name, relationship|
69
77
  if relationship.is_a?(JSONAPI::Relationship::ToMany)
70
78
  jsonapi_links(relationship_name, options)
@@ -78,7 +86,13 @@ module ActionDispatch
78
86
 
79
87
  def jsonapi_resources(*resources, &_block)
80
88
  @resource_type = resources.first
81
- res = JSONAPI::Resource.resource_for(resource_type_with_module_prefix(@resource_type))
89
+ res = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix(@resource_type))
90
+
91
+ res._routed = true
92
+
93
+ if res.singleton?
94
+ warn "Singleton resource #{res} should use `jsonapi_resource` instead."
95
+ end
82
96
 
83
97
  options = resources.extract_options!.dup
84
98
  options[:controller] ||= @resource_type
@@ -102,8 +116,8 @@ module ActionDispatch
102
116
  end
103
117
 
104
118
  if res._immutable
105
- options[:except] << :create unless options[:except].include?(:create) || options[:except].include?('create')
106
- options[:except] << :update unless options[:except].include?(:update) || options[:except].include?('update')
119
+ options[:except] << :create unless options[:except].include?(:create) || options[:except].include?('create')
120
+ options[:except] << :update unless options[:except].include?(:update) || options[:except].include?('update')
107
121
  options[:except] << :destroy unless options[:except].include?(:destroy) || options[:except].include?('destroy')
108
122
  end
109
123
 
@@ -147,25 +161,26 @@ module ActionDispatch
147
161
  formatted_relationship_name = format_route(link_type)
148
162
  options = links.extract_options!.dup
149
163
 
150
- res = JSONAPI::Resource.resource_for(resource_type_with_module_prefix)
164
+ res = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix)
151
165
  options[:controller] ||= res._type.to_s
152
166
 
153
167
  methods = links_methods(options)
154
168
 
155
169
  if methods.include?(:show)
156
170
  match "relationships/#{formatted_relationship_name}", controller: options[:controller],
157
- action: 'show_relationship', relationship: link_type.to_s, via: [:get]
171
+ action: 'show_relationship', relationship: link_type.to_s, via: [:get],
172
+ as: "relationships/#{link_type}"
158
173
  end
159
174
 
160
175
  if res.mutable?
161
176
  if methods.include?(:update)
162
177
  match "relationships/#{formatted_relationship_name}", controller: options[:controller],
163
- action: 'update_relationship', relationship: link_type.to_s, via: [:put, :patch]
178
+ action: 'update_relationship', relationship: link_type.to_s, via: [:put, :patch]
164
179
  end
165
180
 
166
181
  if methods.include?(:destroy)
167
182
  match "relationships/#{formatted_relationship_name}", controller: options[:controller],
168
- action: 'destroy_relationship', relationship: link_type.to_s, via: [:delete]
183
+ action: 'destroy_relationship', relationship: link_type.to_s, via: [:delete]
169
184
  end
170
185
  end
171
186
  end
@@ -175,69 +190,77 @@ module ActionDispatch
175
190
  formatted_relationship_name = format_route(link_type)
176
191
  options = links.extract_options!.dup
177
192
 
178
- res = JSONAPI::Resource.resource_for(resource_type_with_module_prefix)
193
+ res = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix)
179
194
  options[:controller] ||= res._type.to_s
180
195
 
181
196
  methods = links_methods(options)
182
197
 
183
198
  if methods.include?(:show)
184
199
  match "relationships/#{formatted_relationship_name}", controller: options[:controller],
185
- action: 'show_relationship', relationship: link_type.to_s, via: [:get]
200
+ action: 'show_relationship', relationship: link_type.to_s, via: [:get],
201
+ as: "relationships/#{link_type}"
186
202
  end
187
203
 
188
204
  if res.mutable?
189
205
  if methods.include?(:create)
190
206
  match "relationships/#{formatted_relationship_name}", controller: options[:controller],
191
- action: 'create_relationship', relationship: link_type.to_s, via: [:post]
207
+ action: 'create_relationship', relationship: link_type.to_s, via: [:post]
192
208
  end
193
209
 
194
210
  if methods.include?(:update)
195
211
  match "relationships/#{formatted_relationship_name}", controller: options[:controller],
196
- action: 'update_relationship', relationship: link_type.to_s, via: [:put, :patch]
212
+ action: 'update_relationship', relationship: link_type.to_s, via: [:put, :patch]
197
213
  end
198
214
 
199
215
  if methods.include?(:destroy)
200
216
  match "relationships/#{formatted_relationship_name}", controller: options[:controller],
201
- action: 'destroy_relationship', relationship: link_type.to_s, via: [:delete]
217
+ action: 'destroy_relationship', relationship: link_type.to_s, via: [:delete]
202
218
  end
203
219
  end
204
220
  end
205
221
 
206
222
  def jsonapi_related_resource(*relationship)
207
- source = JSONAPI::Resource.resource_for(resource_type_with_module_prefix)
223
+ source = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix)
208
224
  options = relationship.extract_options!.dup
209
225
 
210
226
  relationship_name = relationship.first
211
227
  relationship = source._relationships[relationship_name]
212
228
 
229
+ relationship._routed = true
230
+
213
231
  formatted_relationship_name = format_route(relationship.name)
214
232
 
215
233
  if relationship.polymorphic?
216
234
  options[:controller] ||= relationship.class_name.underscore.pluralize
217
235
  else
218
- related_resource = JSONAPI::Resource.resource_for(resource_type_with_module_prefix(relationship.class_name.underscore.pluralize))
236
+ related_resource = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix(relationship.class_name.underscore.pluralize))
219
237
  options[:controller] ||= related_resource._type.to_s
220
238
  end
221
239
 
222
- match "#{formatted_relationship_name}", controller: options[:controller],
223
- relationship: relationship.name, source: resource_type_with_module_prefix(source._type),
224
- action: 'get_related_resource', via: [:get]
240
+ match formatted_relationship_name, controller: options[:controller],
241
+ relationship: relationship.name, source: resource_type_with_module_prefix(source._type),
242
+ action: 'show_related_resource', via: [:get],
243
+ as: "related/#{relationship_name}"
225
244
  end
226
245
 
227
246
  def jsonapi_related_resources(*relationship)
228
- source = JSONAPI::Resource.resource_for(resource_type_with_module_prefix)
247
+ source = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix)
229
248
  options = relationship.extract_options!.dup
230
249
 
231
250
  relationship_name = relationship.first
232
251
  relationship = source._relationships[relationship_name]
233
252
 
253
+ relationship._routed = true
254
+
234
255
  formatted_relationship_name = format_route(relationship.name)
235
- related_resource = JSONAPI::Resource.resource_for(resource_type_with_module_prefix(relationship.class_name.underscore))
256
+ related_resource = JSONAPI::Resource.resource_klass_for(resource_type_with_module_prefix(relationship.class_name.underscore))
236
257
  options[:controller] ||= related_resource._type.to_s
237
258
 
238
- match "#{formatted_relationship_name}", controller: options[:controller],
239
- relationship: relationship.name, source: resource_type_with_module_prefix(source._type),
240
- action: 'get_related_resources', via: [:get]
259
+ match formatted_relationship_name,
260
+ controller: options[:controller],
261
+ relationship: relationship.name, source: resource_type_with_module_prefix(source._type),
262
+ action: 'index_related_resources', via: [:get],
263
+ as: "related/#{relationship_name}"
241
264
  end
242
265
 
243
266
  protected
@@ -250,6 +273,7 @@ module ActionDispatch
250
273
  @scope = @scope.parent
251
274
  end
252
275
  # :nocov:
276
+
253
277
  private
254
278
 
255
279
  def resource_type_with_module_prefix(resource = nil)
@@ -1,10 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jsonapi/resources/railtie'
1
4
  require 'jsonapi/naive_cache'
2
5
  require 'jsonapi/compiled_json'
6
+ require 'jsonapi/basic_resource'
7
+ require 'jsonapi/active_relation_resource'
3
8
  require 'jsonapi/resource'
4
- require 'jsonapi/cached_resource_fragment'
9
+ require 'jsonapi/cached_response_fragment'
5
10
  require 'jsonapi/response_document'
6
11
  require 'jsonapi/acts_as_resource_controller'
7
- require 'jsonapi/resource_controller'
12
+ if Rails::VERSION::MAJOR >= 6
13
+ ActiveSupport.on_load(:action_controller_base) do
14
+ require 'jsonapi/resource_controller'
15
+ end
16
+ else
17
+ require 'jsonapi/resource_controller'
18
+ end
8
19
  require 'jsonapi/resource_controller_metal'
9
20
  require 'jsonapi/resources/version'
10
21
  require 'jsonapi/configuration'
@@ -16,12 +27,19 @@ require 'jsonapi/resource_serializer'
16
27
  require 'jsonapi/exceptions'
17
28
  require 'jsonapi/error'
18
29
  require 'jsonapi/error_codes'
19
- require 'jsonapi/request_parser'
20
- require 'jsonapi/operation_dispatcher'
30
+ require 'jsonapi/request'
21
31
  require 'jsonapi/processor'
22
32
  require 'jsonapi/relationship'
23
33
  require 'jsonapi/include_directives'
34
+ require 'jsonapi/operation'
24
35
  require 'jsonapi/operation_result'
25
- require 'jsonapi/operation_results'
26
36
  require 'jsonapi/callbacks'
27
37
  require 'jsonapi/link_builder'
38
+ require 'jsonapi/active_relation/adapters/join_left_active_record_adapter'
39
+ require 'jsonapi/active_relation/join_manager'
40
+ require 'jsonapi/resource_identity'
41
+ require 'jsonapi/resource_fragment'
42
+ require 'jsonapi/resource_tree'
43
+ require 'jsonapi/resource_set'
44
+ require 'jsonapi/path'
45
+ require 'jsonapi/path_segment'
@@ -0,0 +1,52 @@
1
+ require 'rake'
2
+ require 'jsonapi-resources'
3
+
4
+ namespace :jsonapi do
5
+ namespace :resources do
6
+ desc 'Checks application for orphaned overrides'
7
+ task :check_upgrade => :environment do
8
+ Rails.application.eager_load!
9
+
10
+ resource_klasses = ObjectSpace.each_object(Class).select { |klass| klass < JSONAPI::Resource}
11
+
12
+ puts "Checking #{resource_klasses.count} resources"
13
+
14
+ issues_found = 0
15
+
16
+ klasses_with_deprecated = resource_klasses.select { |klass| klass.methods.include?(:find_records) }
17
+ unless klasses_with_deprecated.empty?
18
+ puts " Found the following resources the still implement `find_records`:"
19
+ klasses_with_deprecated.each { |klass| puts " #{klass}"}
20
+ puts " The `find_records` method is no longer called by JR. Please review and ensure your functionality is ported over."
21
+
22
+ issues_found = issues_found + klasses_with_deprecated.length
23
+ end
24
+
25
+ klasses_with_deprecated = resource_klasses.select { |klass| klass.methods.include?(:records_for) }
26
+ unless klasses_with_deprecated.empty?
27
+ puts " Found the following resources the still implement `records_for`:"
28
+ klasses_with_deprecated.each { |klass| puts " #{klass}"}
29
+ puts " The `records_for` method is no longer called by JR. Please review and ensure your functionality is ported over."
30
+
31
+ issues_found = issues_found + klasses_with_deprecated.length
32
+ end
33
+
34
+ klasses_with_deprecated = resource_klasses.select { |klass| klass.methods.include?(:apply_includes) }
35
+ unless klasses_with_deprecated.empty?
36
+ puts " Found the following resources the still implement `apply_includes`:"
37
+ klasses_with_deprecated.each { |klass| puts " #{klass}"}
38
+ puts " The `apply_includes` method is no longer called by JR. Please review and ensure your functionality is ported over."
39
+
40
+ issues_found = issues_found + klasses_with_deprecated.length
41
+ end
42
+
43
+ if issues_found > 0
44
+ puts "Finished inspection. #{issues_found} issues found that may impact upgrading. Please address these issues. "
45
+ else
46
+ puts "Finished inspection with no issues found. Note this is only a cursory check for method overrides that will no \n" \
47
+ "longer be called by JSONAPI::Resources. This check in no way assures your code will continue to function as \n" \
48
+ "it did before the upgrade. Please do adequate testing before using in production."
49
+ end
50
+ end
51
+ end
52
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sanger-jsonapi-resources
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - PSD Team - Wellcome Trust Sanger Institute
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-17 00:00:00.000000000 Z
11
+ date: 2025-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,20 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.5'
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: '3.0'
19
+ version: '1.17'
23
20
  type: :development
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
- version: '1.5'
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: '3.0'
26
+ version: '1.17'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: rake
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -48,16 +42,22 @@ dependencies:
48
42
  name: minitest
49
43
  requirement: !ruby/object:Gem::Requirement
50
44
  requirements:
51
- - - ">="
45
+ - - "~>"
52
46
  - !ruby/object:Gem::Version
53
- version: '0'
47
+ version: '5.10'
48
+ - - "!="
49
+ - !ruby/object:Gem::Version
50
+ version: 5.10.2
54
51
  type: :development
55
52
  prerelease: false
56
53
  version_requirements: !ruby/object:Gem::Requirement
57
54
  requirements:
58
- - - ">="
55
+ - - "~>"
59
56
  - !ruby/object:Gem::Version
60
- version: '0'
57
+ version: '5.10'
58
+ - - "!="
59
+ - !ruby/object:Gem::Version
60
+ version: 5.10.2
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: minitest-spec-rails
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -115,49 +115,49 @@ dependencies:
115
115
  - !ruby/object:Gem::Version
116
116
  version: '0'
117
117
  - !ruby/object:Gem::Dependency
118
- name: activerecord
118
+ name: database_cleaner
119
119
  requirement: !ruby/object:Gem::Requirement
120
120
  requirements:
121
121
  - - ">="
122
122
  - !ruby/object:Gem::Version
123
- version: '4.1'
124
- type: :runtime
123
+ version: '0'
124
+ type: :development
125
125
  prerelease: false
126
126
  version_requirements: !ruby/object:Gem::Requirement
127
127
  requirements:
128
128
  - - ">="
129
129
  - !ruby/object:Gem::Version
130
- version: '4.1'
130
+ version: '0'
131
131
  - !ruby/object:Gem::Dependency
132
- name: railties
132
+ name: activerecord
133
133
  requirement: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - ">="
136
136
  - !ruby/object:Gem::Version
137
- version: '4.1'
137
+ version: '5.1'
138
138
  type: :runtime
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - ">="
143
143
  - !ruby/object:Gem::Version
144
- version: '4.1'
144
+ version: '5.1'
145
145
  - !ruby/object:Gem::Dependency
146
- name: concurrent-ruby
146
+ name: railties
147
147
  requirement: !ruby/object:Gem::Requirement
148
148
  requirements:
149
149
  - - ">="
150
150
  - !ruby/object:Gem::Version
151
- version: '0'
151
+ version: '5.1'
152
152
  type: :runtime
153
153
  prerelease: false
154
154
  version_requirements: !ruby/object:Gem::Requirement
155
155
  requirements:
156
156
  - - ">="
157
157
  - !ruby/object:Gem::Version
158
- version: '0'
158
+ version: '5.1'
159
159
  - !ruby/object:Gem::Dependency
160
- name: csv
160
+ name: concurrent-ruby
161
161
  requirement: !ruby/object:Gem::Requirement
162
162
  requirements:
163
163
  - - ">="
@@ -180,15 +180,22 @@ extra_rdoc_files: []
180
180
  files:
181
181
  - LICENSE.txt
182
182
  - README.md
183
+ - lib/bug_report_templates/rails_5_latest.rb
184
+ - lib/bug_report_templates/rails_5_master.rb
183
185
  - lib/generators/jsonapi/USAGE
184
186
  - lib/generators/jsonapi/controller_generator.rb
185
187
  - lib/generators/jsonapi/resource_generator.rb
186
188
  - lib/generators/jsonapi/templates/jsonapi_controller.rb
187
189
  - lib/generators/jsonapi/templates/jsonapi_resource.rb
188
190
  - lib/jsonapi-resources.rb
191
+ - lib/jsonapi/active_relation/adapters/join_left_active_record_adapter.rb
192
+ - lib/jsonapi/active_relation/join_manager.rb
193
+ - lib/jsonapi/active_relation_resource.rb
189
194
  - lib/jsonapi/acts_as_resource_controller.rb
190
- - lib/jsonapi/cached_resource_fragment.rb
195
+ - lib/jsonapi/basic_resource.rb
196
+ - lib/jsonapi/cached_response_fragment.rb
191
197
  - lib/jsonapi/callbacks.rb
198
+ - lib/jsonapi/compatibility_helper.rb
192
199
  - lib/jsonapi/compiled_json.rb
193
200
  - lib/jsonapi/configuration.rb
194
201
  - lib/jsonapi/error.rb
@@ -200,22 +207,27 @@ files:
200
207
  - lib/jsonapi/mime_types.rb
201
208
  - lib/jsonapi/naive_cache.rb
202
209
  - lib/jsonapi/operation.rb
203
- - lib/jsonapi/operation_dispatcher.rb
204
210
  - lib/jsonapi/operation_result.rb
205
- - lib/jsonapi/operation_results.rb
206
211
  - lib/jsonapi/paginator.rb
212
+ - lib/jsonapi/path.rb
213
+ - lib/jsonapi/path_segment.rb
207
214
  - lib/jsonapi/processor.rb
208
215
  - lib/jsonapi/relationship.rb
209
- - lib/jsonapi/relationship_builder.rb
210
- - lib/jsonapi/request_parser.rb
216
+ - lib/jsonapi/request.rb
211
217
  - lib/jsonapi/resource.rb
212
218
  - lib/jsonapi/resource_controller.rb
213
219
  - lib/jsonapi/resource_controller_metal.rb
220
+ - lib/jsonapi/resource_fragment.rb
221
+ - lib/jsonapi/resource_identity.rb
214
222
  - lib/jsonapi/resource_serializer.rb
223
+ - lib/jsonapi/resource_set.rb
224
+ - lib/jsonapi/resource_tree.rb
225
+ - lib/jsonapi/resources/railtie.rb
215
226
  - lib/jsonapi/resources/version.rb
216
227
  - lib/jsonapi/response_document.rb
217
228
  - lib/jsonapi/routing_ext.rb
218
229
  - lib/sanger-jsonapi-resources.rb
230
+ - lib/tasks/check_upgrade.rake
219
231
  homepage: https://github.com/sanger/jsonapi-resources
220
232
  licenses:
221
233
  - MIT
@@ -228,7 +240,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
228
240
  requirements:
229
241
  - - ">="
230
242
  - !ruby/object:Gem::Version
231
- version: '2.1'
243
+ version: '2.3'
232
244
  required_rubygems_version: !ruby/object:Gem::Requirement
233
245
  requirements:
234
246
  - - ">="
@@ -1,127 +0,0 @@
1
- module JSONAPI
2
- class CachedResourceFragment
3
- def self.fetch_fragments(resource_klass, serializer, context, cache_ids)
4
- serializer_config_key = serializer.config_key(resource_klass).gsub("/", "_")
5
- context_json = resource_klass.attribute_caching_context(context).to_json
6
- context_b64 = JSONAPI.configuration.resource_cache_digest_function.call(context_json)
7
- context_key = "ATTR-CTX-#{context_b64.gsub("/", "_")}"
8
-
9
- results = self.lookup(resource_klass, serializer_config_key, context, context_key, cache_ids)
10
-
11
- miss_ids = results.select{|k,v| v.nil? }.keys
12
- unless miss_ids.empty?
13
- find_filters = {resource_klass._primary_key => miss_ids.uniq}
14
- find_options = {context: context}
15
- resource_klass.find(find_filters, find_options).each do |resource|
16
- (id, cr) = write(resource_klass, resource, serializer, serializer_config_key, context, context_key)
17
- results[id] = cr
18
- end
19
- end
20
-
21
- if JSONAPI.configuration.resource_cache_usage_report_function
22
- JSONAPI.configuration.resource_cache_usage_report_function.call(
23
- resource_klass.name,
24
- cache_ids.size - miss_ids.size,
25
- miss_ids.size
26
- )
27
- end
28
-
29
- return results
30
- end
31
-
32
- attr_reader :resource_klass, :id, :type, :context, :fetchable_fields, :relationships,
33
- :links_json, :attributes_json, :meta_json,
34
- :preloaded_fragments
35
-
36
- def initialize(resource_klass, id, type, context, fetchable_fields, relationships,
37
- links_json, attributes_json, meta_json)
38
- @resource_klass = resource_klass
39
- @id = id
40
- @type = type
41
- @context = context
42
- @fetchable_fields = Set.new(fetchable_fields)
43
-
44
- # Relationships left uncompiled because we'll often want to insert included ids on retrieval
45
- @relationships = relationships
46
-
47
- @links_json = CompiledJson.of(links_json)
48
- @attributes_json = CompiledJson.of(attributes_json)
49
- @meta_json = CompiledJson.of(meta_json)
50
-
51
- # A hash of hashes
52
- @preloaded_fragments ||= Hash.new
53
- end
54
-
55
- def to_cache_value
56
- {
57
- id: id,
58
- type: type,
59
- fetchable: fetchable_fields,
60
- rels: relationships,
61
- links: links_json.try(:to_s),
62
- attrs: attributes_json.try(:to_s),
63
- meta: meta_json.try(:to_s)
64
- }
65
- end
66
-
67
- def to_real_resource
68
- rs = Resource.resource_for(self.type).find_by_keys([self.id], {context: self.context})
69
- return rs.try(:first)
70
- end
71
-
72
- private
73
-
74
- def self.lookup(resource_klass, serializer_config_key, context, context_key, cache_ids)
75
- type = resource_klass._type
76
-
77
- keys = cache_ids.map do |(id, cache_key)|
78
- [type, id, cache_key, serializer_config_key, context_key]
79
- end
80
-
81
- hits = JSONAPI.configuration.resource_cache.read_multi(*keys).reject{|_,v| v.nil? }
82
- return keys.each_with_object({}) do |key, hash|
83
- (_, id, _, _) = key
84
- if hits.has_key?(key)
85
- hash[id] = self.from_cache_value(resource_klass, context, hits[key])
86
- else
87
- hash[id] = nil
88
- end
89
- end
90
- end
91
-
92
- def self.from_cache_value(resource_klass, context, h)
93
- new(
94
- resource_klass,
95
- h.fetch(:id),
96
- h.fetch(:type),
97
- context,
98
- h.fetch(:fetchable),
99
- h.fetch(:rels, nil),
100
- h.fetch(:links, nil),
101
- h.fetch(:attrs, nil),
102
- h.fetch(:meta, nil)
103
- )
104
- end
105
-
106
- def self.write(resource_klass, resource, serializer, serializer_config_key, context, context_key)
107
- (id, cache_key) = resource.cache_id
108
- json = serializer.object_hash(resource) # No inclusions passed to object_hash
109
- cr = self.new(
110
- resource_klass,
111
- json['id'],
112
- json['type'],
113
- context,
114
- resource.fetchable_fields,
115
- json['relationships'],
116
- json['links'],
117
- json['attributes'],
118
- json['meta']
119
- )
120
-
121
- key = [resource_klass._type, id, cache_key, serializer_config_key, context_key]
122
- JSONAPI.configuration.resource_cache.write(key, cr.to_cache_value)
123
- return [id, cr]
124
- end
125
-
126
- end
127
- end