jsonapi-resources 0.9.5 → 0.9.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/lib/jsonapi/processor.rb +1 -1
- data/lib/jsonapi/request_parser.rb +58 -31
- data/lib/jsonapi/resource.rb +27 -0
- data/lib/jsonapi/resource_serializer.rb +5 -4
- data/lib/jsonapi/resources/version.rb +1 -1
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: aca973f2c9c1164fc79771cc71b363be15d07159cbe8d2b273d63886fee30b05
|
4
|
+
data.tar.gz: cdd800dde1c3f08d6b7c1d6f904f7519f0168c7585a4a9e6b8d4ecf89e834e1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 509137860c1e0a0a842a15ebeb580e229cc0636623ebc3d70aef2d752979bd066dc6ba2268bbdad483acdc1a5c25701c62eb9876b796effa80dd2e841fd4ef4d
|
7
|
+
data.tar.gz: b9dfc40e043337a749502f70f790e9280bf08e8a267bf0181e48522b27f58b8d1205cce28bc7e866adc6c566399cc313f3442a4aba86b1a6ef256e36b0f50873
|
data/lib/jsonapi/processor.rb
CHANGED
@@ -197,7 +197,7 @@ module JSONAPI
|
|
197
197
|
(paginator && paginator.class.requires_record_count) ||
|
198
198
|
(JSONAPI.configuration.top_level_meta_include_page_count))
|
199
199
|
related_resource_records = source_resource.public_send("records_for_" + relationship_type)
|
200
|
-
records = resource_klass.filter_records(verified_filters,
|
200
|
+
records = resource_klass.filter_records(verified_filters, rel_opts,
|
201
201
|
related_resource_records)
|
202
202
|
|
203
203
|
record_count = resource_klass.count_records(records)
|
@@ -251,34 +251,41 @@ module JSONAPI
|
|
251
251
|
end
|
252
252
|
|
253
253
|
filters.each do |key, value|
|
254
|
-
filter_method, included_resource_name =
|
255
|
-
key.to_s.split('.').map { |k| unformat_key(k) }.reverse
|
256
254
|
|
257
|
-
|
258
|
-
|
255
|
+
unformatted_key = unformat_key(key)
|
256
|
+
if resource_klass._allowed_filter?(unformatted_key)
|
257
|
+
@filters[unformatted_key] = value
|
258
|
+
elsif unformatted_key.to_s.include?('.')
|
259
|
+
parse_relationship_filter(unformatted_key, value)
|
260
|
+
else
|
261
|
+
return @errors.concat(Exceptions::FilterNotAllowed.new(unformatted_key).errors)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
259
265
|
|
260
|
-
|
261
|
-
|
262
|
-
|
266
|
+
def parse_relationship_filter(key, value)
|
267
|
+
included_resource_name, filter_method = key.to_s.split('.')
|
268
|
+
filter_method = filter_method.to_sym if filter_method.present?
|
263
269
|
|
264
|
-
|
265
|
-
|
266
|
-
end
|
270
|
+
if included_resource_name
|
271
|
+
relationship = resource_klass._relationship(included_resource_name || '')
|
267
272
|
|
268
|
-
|
269
|
-
|
270
|
-
|
273
|
+
unless relationship
|
274
|
+
return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
|
275
|
+
end
|
271
276
|
|
272
|
-
|
273
|
-
@
|
274
|
-
|
275
|
-
else
|
276
|
-
unless resource_klass._allowed_filter?(filter_method)
|
277
|
-
return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
|
278
|
-
end
|
277
|
+
unless relationship.resource_klass._allowed_filter?(filter_method)
|
278
|
+
return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
|
279
|
+
end
|
279
280
|
|
280
|
-
|
281
|
+
unless @include_directives.try(:include_config, relationship.name.to_sym).present?
|
282
|
+
return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
|
281
283
|
end
|
284
|
+
|
285
|
+
verified_filter = relationship.resource_klass.verify_filters(filter_method => value)
|
286
|
+
@include_directives.merge_filter(relationship.name, verified_filter)
|
287
|
+
else
|
288
|
+
return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
|
282
289
|
end
|
283
290
|
end
|
284
291
|
|
@@ -521,20 +528,40 @@ module JSONAPI
|
|
521
528
|
|
522
529
|
links_object = parse_to_many_links_object(linkage)
|
523
530
|
|
524
|
-
# Since we do not yet support polymorphic to_many relationships we will raise an error if the type does not match the
|
525
|
-
# relationship's type.
|
526
|
-
# ToDo: Support Polymorphic relationships
|
527
|
-
|
528
531
|
if links_object.length == 0
|
529
532
|
add_result.call([])
|
530
533
|
else
|
531
|
-
if
|
532
|
-
|
533
|
-
|
534
|
+
if relationship.polymorphic?
|
535
|
+
polymorphic_results = []
|
536
|
+
|
537
|
+
links_object.each_pair do |type, keys|
|
538
|
+
resource = self.resource_klass || Resource
|
539
|
+
type_name = unformat_key(type).to_s
|
540
|
+
|
541
|
+
relationship_resource_klass = resource.resource_for(relationship.class_name)
|
542
|
+
relationship_klass = relationship_resource_klass._model_class
|
543
|
+
|
544
|
+
linkage_object_resource_klass = resource.resource_for(type_name)
|
545
|
+
linkage_object_klass = linkage_object_resource_klass._model_class
|
546
|
+
|
547
|
+
unless linkage_object_klass == relationship_klass || linkage_object_klass.in?(relationship_klass.subclasses)
|
548
|
+
fail JSONAPI::Exceptions::TypeMismatch.new(type_name)
|
549
|
+
end
|
550
|
+
|
551
|
+
relationship_ids = relationship_resource_klass.verify_keys(keys, @context)
|
552
|
+
polymorphic_results << { type: type, ids: relationship_ids }
|
553
|
+
end
|
554
|
+
|
555
|
+
add_result.call polymorphic_results
|
556
|
+
else
|
557
|
+
relationship_type = unformat_key(relationship.type).to_s
|
558
|
+
|
559
|
+
if links_object.length > 1 || !links_object.has_key?(relationship_type)
|
560
|
+
fail JSONAPI::Exceptions::TypeMismatch.new(links_object[:type])
|
561
|
+
end
|
534
562
|
|
535
|
-
|
536
|
-
relationship_resource
|
537
|
-
add_result.call relationship_resource.verify_keys(keys, @context)
|
563
|
+
relationship_resource = Resource.resource_for(@resource_klass.module_path + relationship_type)
|
564
|
+
add_result.call relationship_resource.verify_keys(links_object[relationship_type], @context)
|
538
565
|
end
|
539
566
|
end
|
540
567
|
end
|
data/lib/jsonapi/resource.rb
CHANGED
@@ -302,6 +302,26 @@ module JSONAPI
|
|
302
302
|
to_add = relationship_key_values - (relationship_key_values & existing)
|
303
303
|
_create_to_many_links(relationship_type, to_add, {})
|
304
304
|
|
305
|
+
@reload_needed = true
|
306
|
+
elsif relationship.polymorphic?
|
307
|
+
relationship_key_values.each do |relationship_key_value|
|
308
|
+
relationship_resource_klass = self.class.resource_for(relationship_key_value[:type])
|
309
|
+
ids = relationship_key_value[:ids]
|
310
|
+
|
311
|
+
related_records = relationship_resource_klass
|
312
|
+
.records(options)
|
313
|
+
.where({relationship_resource_klass._primary_key => ids})
|
314
|
+
|
315
|
+
missed_ids = ids - related_records.pluck(relationship_resource_klass._primary_key)
|
316
|
+
|
317
|
+
if missed_ids.present?
|
318
|
+
fail JSONAPI::Exceptions::RecordNotFound.new(missed_ids)
|
319
|
+
end
|
320
|
+
|
321
|
+
relation_name = relationship.relation_name(context: @context)
|
322
|
+
@model.send("#{relation_name}") << related_records
|
323
|
+
end
|
324
|
+
|
305
325
|
@reload_needed = true
|
306
326
|
else
|
307
327
|
send("#{relationship.foreign_key}=", relationship_key_values)
|
@@ -565,7 +585,14 @@ module JSONAPI
|
|
565
585
|
_add_relationship(Relationship::ToMany, *attrs)
|
566
586
|
end
|
567
587
|
|
588
|
+
# @model_class is inherited from superclass, and this causes some issues:
|
589
|
+
# ```
|
590
|
+
# CarResource._model_class #=> Vehicle # it should be Car
|
591
|
+
# ```
|
592
|
+
# so in order to invoke the right class from subclasses,
|
593
|
+
# we should call this method to override it.
|
568
594
|
def model_name(model, options = {})
|
595
|
+
@model_class = nil
|
569
596
|
@_model_name = model.to_sym
|
570
597
|
|
571
598
|
model_hint(model: @_model_name, resource: self) unless options[:add_model_hint] == false
|
@@ -394,12 +394,16 @@ module JSONAPI
|
|
394
394
|
|
395
395
|
def to_many_linkage(source, relationship)
|
396
396
|
linkage = []
|
397
|
+
include_config = include_directives.include_config(relationship.name.to_sym) if include_directives
|
398
|
+
include_filters = include_config[:include_filters] if include_config
|
399
|
+
options = { filters: include_filters || {} }
|
400
|
+
|
397
401
|
linkage_types_and_values = if source.preloaded_fragments.has_key?(format_key(relationship.name))
|
398
402
|
source.preloaded_fragments[format_key(relationship.name)].map do |_, resource|
|
399
403
|
[relationship.type, resource.id]
|
400
404
|
end
|
401
405
|
elsif relationship.polymorphic?
|
402
|
-
assoc = source.
|
406
|
+
assoc = source.public_send("records_for_#{relationship.name}", options)
|
403
407
|
# Avoid hitting the database again for values already pre-loaded
|
404
408
|
if assoc.respond_to?(:loaded?) and assoc.loaded?
|
405
409
|
assoc.map do |obj|
|
@@ -411,9 +415,6 @@ module JSONAPI
|
|
411
415
|
end
|
412
416
|
end
|
413
417
|
else
|
414
|
-
include_config = include_directives.include_config(relationship.name.to_sym) if include_directives
|
415
|
-
include_filters = include_config[:include_filters] if include_config
|
416
|
-
options = { filters: include_filters || {} }
|
417
418
|
source.public_send(relationship.name, options).map do |value|
|
418
419
|
[relationship.type, value.id]
|
419
420
|
end
|
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.6
|
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-
|
12
|
+
date: 2019-03-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -109,6 +109,20 @@ dependencies:
|
|
109
109
|
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: '0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: database_cleaner
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
112
126
|
- !ruby/object:Gem::Dependency
|
113
127
|
name: activerecord
|
114
128
|
requirement: !ruby/object:Gem::Requirement
|
@@ -217,7 +231,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
217
231
|
version: '0'
|
218
232
|
requirements: []
|
219
233
|
rubyforge_project:
|
220
|
-
rubygems_version: 2.6
|
234
|
+
rubygems_version: 2.7.6
|
221
235
|
signing_key:
|
222
236
|
specification_version: 4
|
223
237
|
summary: Easily support JSON API in Rails.
|