jsonapi-resources 0.9.5 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 9d5578a1c15d0e7c0c5726406827aa473dd39349
4
- data.tar.gz: 6ded3ed7fc3b01a7811d8a58159cb54c27ec7e26
2
+ SHA256:
3
+ metadata.gz: aca973f2c9c1164fc79771cc71b363be15d07159cbe8d2b273d63886fee30b05
4
+ data.tar.gz: cdd800dde1c3f08d6b7c1d6f904f7519f0168c7585a4a9e6b8d4ecf89e834e1c
5
5
  SHA512:
6
- metadata.gz: 72967c7e6284bc8c0e667fae9899173dc985d4ebd7986a4aa891d4b17154b6c337bd7784acee269224aae5b5f97040d80a6e74db85fd2068155ce8fdadd5fc84
7
- data.tar.gz: 1146acf9b97328aef64efb8a6ed675b3a5e1378a08eeb18fc85f91f548dcf821ec939a9e70271ff3d2fd6ff8e0cfb30de60df2d08ba91ce59858361cdc4e3819
6
+ metadata.gz: 509137860c1e0a0a842a15ebeb580e229cc0636623ebc3d70aef2d752979bd066dc6ba2268bbdad483acdc1a5c25701c62eb9876b796effa80dd2e841fd4ef4d
7
+ data.tar.gz: b9dfc40e043337a749502f70f790e9280bf08e8a267bf0181e48522b27f58b8d1205cce28bc7e866adc6c566399cc313f3442a4aba86b1a6ef256e36b0f50873
@@ -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
- if included_resource_name
258
- relationship = resource_klass._relationship(included_resource_name || '')
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
- unless relationship
261
- return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
262
- end
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
- unless relationship.resource_klass._allowed_filter?(filter_method)
265
- return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
266
- end
270
+ if included_resource_name
271
+ relationship = resource_klass._relationship(included_resource_name || '')
267
272
 
268
- unless @include_directives.include_config(relationship.name.to_sym).present?
269
- return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
270
- end
273
+ unless relationship
274
+ return @errors.concat(Exceptions::FilterNotAllowed.new(filter_method).errors)
275
+ end
271
276
 
272
- verified_filter = relationship.resource_klass.verify_filters(filter_method => value)
273
- @include_directives.merge_filter(relationship.name, verified_filter)
274
- next
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
- @filters[filter_method] = value
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 links_object.length > 1 || !links_object.has_key?(unformat_key(relationship.type).to_s)
532
- fail JSONAPI::Exceptions::TypeMismatch.new(links_object[:type])
533
- end
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
- links_object.each_pair do |type, keys|
536
- relationship_resource = Resource.resource_for(@resource_klass.module_path + unformat_key(type).to_s)
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
@@ -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._model.public_send(relationship.name)
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
@@ -1,5 +1,5 @@
1
1
  module JSONAPI
2
2
  module Resources
3
- VERSION = '0.9.5'
3
+ VERSION = '0.9.6'
4
4
  end
5
5
  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.5
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-01-09 00:00:00.000000000 Z
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.14.1
234
+ rubygems_version: 2.7.6
221
235
  signing_key:
222
236
  specification_version: 4
223
237
  summary: Easily support JSON API in Rails.