jsonapi_compliable 0.9.2 → 0.10.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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/docs/Jsonapi/ResourceGenerator.html +1 -1
  3. data/docs/Jsonapi.html +1 -1
  4. data/docs/JsonapiCompliable/Adapters/Abstract.html +1 -1
  5. data/docs/JsonapiCompliable/Adapters/ActiveRecord.html +1 -1
  6. data/docs/JsonapiCompliable/Adapters/ActiveRecordSideloading.html +1 -1
  7. data/docs/JsonapiCompliable/Adapters/Null.html +1 -1
  8. data/docs/JsonapiCompliable/Adapters.html +1 -1
  9. data/docs/JsonapiCompliable/Base.html +389 -62
  10. data/docs/JsonapiCompliable/Deserializer.html +1 -1
  11. data/docs/JsonapiCompliable/Errors/BadFilter.html +1 -1
  12. data/docs/JsonapiCompliable/Errors/StatNotFound.html +1 -1
  13. data/docs/JsonapiCompliable/Errors/UnsupportedPageSize.html +1 -1
  14. data/docs/JsonapiCompliable/Errors/ValidationError.html +1 -1
  15. data/docs/JsonapiCompliable/Errors.html +1 -1
  16. data/docs/JsonapiCompliable/Extensions/BooleanAttribute/ClassMethods.html +1 -1
  17. data/docs/JsonapiCompliable/Extensions/BooleanAttribute.html +1 -1
  18. data/docs/JsonapiCompliable/Extensions/ExtraAttribute/ClassMethods.html +1 -1
  19. data/docs/JsonapiCompliable/Extensions/ExtraAttribute.html +1 -1
  20. data/docs/JsonapiCompliable/Extensions.html +1 -1
  21. data/docs/JsonapiCompliable/Query.html +27 -21
  22. data/docs/JsonapiCompliable/Rails.html +1 -1
  23. data/docs/JsonapiCompliable/Resource.html +189 -572
  24. data/docs/JsonapiCompliable/Scope.html +1 -1
  25. data/docs/JsonapiCompliable/Scoping/Base.html +1 -1
  26. data/docs/JsonapiCompliable/Scoping/DefaultFilter.html +1 -1
  27. data/docs/JsonapiCompliable/Scoping/ExtraFields.html +1 -1
  28. data/docs/JsonapiCompliable/Scoping/Filter.html +1 -1
  29. data/docs/JsonapiCompliable/Scoping/Filterable.html +1 -1
  30. data/docs/JsonapiCompliable/Scoping/Paginate.html +1 -1
  31. data/docs/JsonapiCompliable/Scoping/Sort.html +1 -1
  32. data/docs/JsonapiCompliable/Scoping.html +1 -1
  33. data/docs/JsonapiCompliable/SerializableTempId.html +1 -1
  34. data/docs/JsonapiCompliable/Sideload.html +164 -384
  35. data/docs/JsonapiCompliable/Stats/DSL.html +1 -1
  36. data/docs/JsonapiCompliable/Stats/Payload.html +1 -1
  37. data/docs/JsonapiCompliable/Stats.html +1 -1
  38. data/docs/JsonapiCompliable/Util/FieldParams.html +1 -1
  39. data/docs/JsonapiCompliable/Util/Hash.html +1 -1
  40. data/docs/JsonapiCompliable/Util/IncludeParams.html +1 -1
  41. data/docs/JsonapiCompliable/Util/Persistence.html +1 -1
  42. data/docs/JsonapiCompliable/Util/RelationshipPayload.html +1 -1
  43. data/docs/JsonapiCompliable/Util/RenderOptions.html +1 -1
  44. data/docs/JsonapiCompliable/Util/ValidationResponse.html +1 -1
  45. data/docs/JsonapiCompliable/Util.html +1 -1
  46. data/docs/JsonapiCompliable.html +2 -2
  47. data/docs/_index.html +1 -1
  48. data/docs/file.README.html +1 -1
  49. data/docs/index.html +1 -1
  50. data/docs/method_list.html +191 -215
  51. data/docs/top-level-namespace.html +1 -1
  52. data/lib/jsonapi_compliable/base.rb +43 -1
  53. data/lib/jsonapi_compliable/query.rb +8 -5
  54. data/lib/jsonapi_compliable/resource.rb +2 -90
  55. data/lib/jsonapi_compliable/scope.rb +2 -4
  56. data/lib/jsonapi_compliable/sideload.rb +7 -59
  57. data/lib/jsonapi_compliable/version.rb +1 -1
  58. metadata +2 -2
@@ -100,7 +100,7 @@
100
100
  </div>
101
101
 
102
102
  <div id="footer">
103
- Generated on Mon Oct 2 09:38:49 2017 by
103
+ Generated on Tue Oct 3 09:22:25 2017 by
104
104
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
105
105
  0.9.9 (ruby-2.3.0).
106
106
  </div>
@@ -7,12 +7,13 @@ module JsonapiCompliable
7
7
 
8
8
  included do
9
9
  class << self
10
- attr_accessor :_jsonapi_compliable
10
+ attr_accessor :_jsonapi_compliable, :_sideload_whitelist
11
11
  end
12
12
 
13
13
  def self.inherited(klass)
14
14
  super
15
15
  klass._jsonapi_compliable = Class.new(_jsonapi_compliable)
16
+ klass._sideload_whitelist = _sideload_whitelist.dup if _sideload_whitelist
16
17
  end
17
18
  end
18
19
 
@@ -52,6 +53,47 @@ module JsonapiCompliable
52
53
 
53
54
  self._jsonapi_compliable.class_eval(&blk) if blk
54
55
  end
56
+
57
+ # Set the sideload whitelist. You may want to omit sideloads for
58
+ # security or performance reasons.
59
+ #
60
+ # Uses JSONAPI::IncludeDirective from {{http://jsonapi-rb.org jsonapi-rb}}
61
+ #
62
+ # @example Whitelisting Relationships
63
+ # # Given the following whitelist
64
+ # class PostsController < ApplicationResource
65
+ # jsonapi resource: MyResource
66
+ #
67
+ # sideload_whitelist({
68
+ # index: [:blog],
69
+ # show: [:blog, { comments: :author }]
70
+ # })
71
+ #
72
+ # # ... code ...
73
+ # end
74
+ #
75
+ # # A request to sideload 'tags'
76
+ # #
77
+ # # GET /posts/1?include=tags
78
+ # #
79
+ # # ...will silently fail.
80
+ # #
81
+ # # A request for comments and tags:
82
+ # #
83
+ # # GET /posts/1?include=tags,comments
84
+ # #
85
+ # # ...will only sideload comments
86
+ #
87
+ # @param [Hash, Array, Symbol] whitelist
88
+ # @see Query#include_hash
89
+ def sideload_whitelist(hash)
90
+ self._sideload_whitelist = JSONAPI::IncludeDirective.new(hash).to_hash
91
+ end
92
+ end
93
+
94
+ # @api private
95
+ def sideload_whitelist
96
+ self.class._sideload_whitelist || {}
55
97
  end
56
98
 
57
99
  # Returns an instance of the associated Resource
@@ -49,12 +49,15 @@ module JsonapiCompliable
49
49
  # @return [Hash] the scrubbed include directive as a hash
50
50
  def include_hash
51
51
  @include_hash ||= begin
52
- requested = include_directive.to_hash
53
- all_allowed = resource.sideloading.to_hash[:base]
54
- whitelist = resource.sideload_whitelist.values.reduce(:merge)
55
- allowed = whitelist ? Util::IncludeParams.scrub(all_allowed, whitelist) : all_allowed
52
+ requested = include_directive.to_hash
56
53
 
57
- Util::IncludeParams.scrub(requested, allowed)
54
+ whitelist = nil
55
+ if resource.context
56
+ whitelist = resource.context.sideload_whitelist
57
+ whitelist = whitelist[resource.context_namespace] if whitelist
58
+ end
59
+
60
+ whitelist ? Util::IncludeParams.scrub(requested, whitelist) : requested
58
61
  end
59
62
  end
60
63
 
@@ -132,36 +132,6 @@ module JsonapiCompliable
132
132
  @sideloading ||= Sideload.new(:base, resource: self)
133
133
  end
134
134
 
135
- # Set the sideload whitelist. You may want to omit sideloads for
136
- # security or performance reasons.
137
- #
138
- # Uses JSONAPI::IncludeDirective from {{http://jsonapi-rb.org jsonapi-rb}}
139
- #
140
- # @example Whitelisting Relationships
141
- # # Given the following whitelist
142
- # class PostResource < ApplicationResource
143
- # # ... code ...
144
- # sideload_whitelist([:blog, { comments: :author }])
145
- # end
146
- #
147
- # # A request to sideload 'tags'
148
- # #
149
- # # GET /posts?include=tags
150
- # #
151
- # # ...will silently fail.
152
- # #
153
- # # A request for comments and tags:
154
- # #
155
- # # GET /posts?include=tags,comments
156
- # #
157
- # # ...will only sideload comments
158
- #
159
- # @param [Hash, Array, Symbol] whitelist
160
- # @see Query#include_hash
161
- def self.sideload_whitelist(whitelist)
162
- config[:sideload_whitelist] = JSONAPI::IncludeDirective.new(whitelist).to_hash
163
- end
164
-
165
135
  # Whitelist a filter
166
136
  #
167
137
  # @example Basic Filtering
@@ -413,7 +383,6 @@ module JsonapiCompliable
413
383
  def self.config
414
384
  @config ||= begin
415
385
  {
416
- sideload_whitelist: {},
417
386
  filters: {},
418
387
  default_filters: {},
419
388
  extra_fields: {},
@@ -568,60 +537,9 @@ module JsonapiCompliable
568
537
  persistence.run
569
538
  end
570
539
 
571
- # All possible sideload names, including nested names
572
- #
573
- # { comments: { author: {} } }
574
- #
575
- # Becomes
576
- #
577
- # [:comments, :author]
578
- #
579
- # @see Sideload#to_hash
580
- # @return [Array<Symbol>] the list of association names
540
+ # @see Sideload#association_names
581
541
  def association_names
582
- @association_names ||= begin
583
- if sideloading
584
- Util::Hash.keys(sideloading.to_hash[:base])
585
- else
586
- []
587
- end
588
- end
589
- end
590
-
591
- # An Include Directive Hash of all possible sideloads for the current
592
- # context namespace, taking into account the sideload whitelist.
593
- #
594
- # In other words, say we have this resource:
595
- #
596
- # class PostResource < ApplicationResource
597
- # sideload_whitelist({
598
- # index: :comments,
599
- # show: { comments: :author }
600
- # })
601
- # end
602
- #
603
- # Expected behavior:
604
- #
605
- # allowed_sideloads(:index) # => { comments: {} }
606
- # allowed_sideloads(:show) # => { comments: { author: {} }
607
- #
608
- # instance.with_context({}, :index) do
609
- # instance.allowed_sideloads # => { comments: {} }
610
- # end
611
- #
612
- # @see Util::IncludeParams.scrub
613
- # @see #with_context
614
- # @param [Symbol] namespace Can be :index/:show/etc - The current context namespace will be used by default.
615
- # @return [Hash] the scrubbed include directive
616
- def allowed_sideloads(namespace = nil)
617
- return {} unless sideloading
618
-
619
- namespace ||= context_namespace
620
- sideloads = sideloading.to_hash[:base]
621
- if !sideload_whitelist.empty? && namespace
622
- sideloads = Util::IncludeParams.scrub(sideloads, sideload_whitelist[namespace])
623
- end
624
- sideloads
542
+ sideloading.association_names
625
543
  end
626
544
 
627
545
  # The relevant proc for the given attribute and calculation.
@@ -710,12 +628,6 @@ module JsonapiCompliable
710
628
  self.class.config[:extra_fields]
711
629
  end
712
630
 
713
- # @see .sideload_whitelist
714
- # @api private
715
- def sideload_whitelist
716
- self.class.config[:sideload_whitelist]
717
- end
718
-
719
631
  # @see .default_filter
720
632
  # @api private
721
633
  def default_filters
@@ -80,10 +80,8 @@ module JsonapiCompliable
80
80
  return if results == []
81
81
 
82
82
  includes.each_pair do |name, nested|
83
- if @resource.allowed_sideloads.has_key?(name)
84
- sideload = @resource.sideload(name)
85
- sideload.resolve(results, @query)
86
- end
83
+ sideload = @resource.sideload(name)
84
+ sideload.resolve(results, @query)
87
85
  end
88
86
  end
89
87
 
@@ -43,21 +43,6 @@ module JsonapiCompliable
43
43
  extend @resource_class.config[:adapter].sideloading_module
44
44
  end
45
45
 
46
- # @api private
47
- def self.max_recursion
48
- @max_recursion || 2
49
- end
50
-
51
- # Set maximum levels of sideload recursion
52
- # /authors?comments.authors would be one level
53
- # /authors?comments.authors.comments.authors would be two levels
54
- # etc
55
- #
56
- # Default max recursion is 2
57
- def self.max_recursion=(val)
58
- @max_recursion = val
59
- end
60
-
61
46
  # @see #resource_class
62
47
  # @return [Resource] an instance of +#resource_class+
63
48
  def resource
@@ -359,44 +344,15 @@ module JsonapiCompliable
359
344
  end
360
345
  end
361
346
 
362
- # Looks at all nested sideload, and all nested sideloads for the
363
- # corresponding Resources, and returns an Include Directive hash
364
- #
365
- # For instance, this configuration:
366
- #
367
- # class BarResource < ApplicationResource
368
- # allow_sideload :baz do
369
- # end
370
- # end
371
- #
372
- # class PostResource < ApplicationResource
373
- # allow_sideload :foo do
374
- # allow_sideload :bar, resource: BarResource do
375
- # end
376
- # end
377
- # end
378
- #
379
- # +post_resource.sideloading.to_hash+ would return
380
- #
381
- # { base: { foo: { bar: { baz: {} } } } }
382
- #
383
- # @return [Hash] The nested include hash
384
- # @api private
385
- def to_hash(recursion_chain = [], parent = nil)
386
- recursing = ->(arr) { arr == [parent.object_id, self.object_id] }
387
- recursions = recursion_chain.select(&recursing).length
388
- return {} if recursions >= self.class.max_recursion
389
-
390
- unless (parent && parent.name == :base) || name == :base
391
- recursion_chain += [[parent.object_id, self.object_id]]
392
- end
393
-
394
- { name => {} }.tap do |hash|
395
- all_sideloads.each_pair do |key, sl|
396
- sideload_hash = sl.to_hash(recursion_chain, self)
397
- hash[name].merge!(sideload_hash)
347
+ def association_names(memo = [])
348
+ all_sideloads.each_pair do |name, sl|
349
+ unless memo.include?(sl.name)
350
+ memo << sl.name
351
+ memo |= sl.association_names(memo)
398
352
  end
399
353
  end
354
+
355
+ memo
400
356
  end
401
357
 
402
358
  # @api private
@@ -417,14 +373,6 @@ module JsonapiCompliable
417
373
 
418
374
  private
419
375
 
420
- def nested_sideload_hash(sideload, processed)
421
- {}.tap do |hash|
422
- if sideloading = sideload.resource_class.sideloading
423
- hash.merge!(sideloading.to_hash(processed)[:base])
424
- end
425
- end
426
- end
427
-
428
376
  def polymorphic_grouper(grouping_field)
429
377
  lambda do |record|
430
378
  if record.is_a?(Hash)
@@ -1,3 +1,3 @@
1
1
  module JsonapiCompliable
2
- VERSION = "0.9.2"
2
+ VERSION = "0.10.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi_compliable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Richmond
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2017-10-02 00:00:00.000000000 Z
12
+ date: 2017-10-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: jsonapi-serializable