jsonapi_compliable 0.9.2 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
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