11module JSONAPICompliable
2- class BadFilter < StandardError ; end
3- class UnsupportedPageSize < StandardError ; end
4-
52 module Base
63 extend ActiveSupport ::Concern
74 include Deserializable
85
96 MAX_PAGE_SIZE = 1_000
107
11- class JsonApiConfig
12- attr_accessor :_includes ,
13- :_default_filters ,
14- :_extra_fields ,
15- :_filters ,
16- :_sort ,
17- :_paginate
18-
19- def initialize
20- @_includes = { }
21- @_filters = { }
22- @_default_filters = { }
23- @_extra_fields = { }
24- @_sort = nil
25- @_paginate = nil
26- end
27-
28- def includes ( whitelist : nil , &blk )
29- whitelist = parse_includes ( whitelist ) if whitelist
30-
31- @_includes = {
32- whitelist : whitelist ,
33- custom_function : blk
34- }
35- end
36-
37- def allow_filter ( name , *args , &blk )
38- opts = args . extract_options!
39- aliases = [ name , opts [ :aliases ] ] . flatten . compact
40- @_filters [ name . to_sym ] = {
41- aliases : aliases ,
42- if : opts [ :if ] ,
43- filter : blk
44- }
45- end
46-
47- def default_filter ( name , &blk )
48- @_default_filters [ name . to_sym ] = {
49- filter : blk
50- }
51- end
52-
53- def sort ( &blk )
54- @_sort = blk
55- end
56-
57- def paginate ( &blk )
58- @_paginate = blk
59- end
60-
61- def extra_field ( field , &blk )
62- @_extra_fields [ field . keys . first ] ||= [ ]
63- @_extra_fields [ field . keys . first ] << {
64- name : field . values . first ,
65- proc : blk
66- }
67- end
68-
69- def parse_includes ( includes )
70- JSONAPI ::IncludeDirective . new ( includes )
71- end
72-
73- def filter_scope ( controller , scope , name , value )
74- name = name . to_sym
75- filter = find_filter! ( controller , name )
76- value = value . split ( ',' ) if value . include? ( ',' )
77-
78- if custom_scope = filter . values . first [ :filter ]
79- custom_scope . call ( scope , value )
80- else
81- scope . where ( filter . keys . first => value )
82- end
83- end
84-
85- def default_filter_scope ( controller , scope )
86- @_default_filters . each_pair do |name , opts |
87- next if find_filter ( controller , name )
88- scope = opts [ :filter ] . call ( scope )
89- end
90-
91- scope
92- end
93-
94- private
95-
96- def find_filter ( controller , name )
97- find_filter! ( controller , name )
98- rescue BadFilter
99- nil
100- end
101-
102- def find_filter! ( controller , name )
103- filter_name , filter_value = \
104- @_filters . find { |_name , opts | opts [ :aliases ] . include? ( name . to_sym ) }
105- raise BadFilter unless filter_name
106- if guard = filter_value [ :if ]
107- raise BadFilter if controller . send ( guard ) == false
108- end
109- { filter_name => filter_value }
110- end
111- end
112-
1138 included do
114- class_attribute :_jsonapi_config
9+ class_attribute :_jsonapi_compliable
11510
11611 def self . inherited ( klass )
117- klass . _jsonapi_config = nil
12+ klass . _jsonapi_compliable = nil
11813 end
11914
12015 before_action :parse_fieldsets!
@@ -141,16 +36,16 @@ def self.call(includes, whitelist)
14136 def scrub_includes
14237 return unless params [ :include ]
14338
144- includes = _jsonapi_config . parse_includes ( params [ :include ] )
145- whitelist = _jsonapi_config . _includes [ :whitelist ] [ params [ :action ] ]
39+ includes = _jsonapi_compliable . parse_includes ( params [ :include ] )
40+ whitelist = _jsonapi_compliable . sideloads [ :whitelist ] [ params [ :action ] ]
14641 whitelist ? CompareIncludes . call ( includes , whitelist ) : { }
14742 end
14843
14944 def jsonapi_includes ( scope )
15045 scrubbed = scrub_includes
15146 return scope unless scrubbed
15247
153- scope = if custom_include = _jsonapi_config . _includes [ :custom_function ]
48+ scope = if custom_include = _jsonapi_compliable . sideloads [ :custom_function ]
15449 custom_include . call ( scope , scrubbed )
15550 else
15651 scope . includes ( scrubbed )
@@ -164,7 +59,7 @@ def jsonapi_sort(scope)
16459 dir = sort_param . starts_with? ( '-' ) ? :desc : :asc
16560 att = sort_param . sub ( '-' , '' ) . to_sym
16661
167- scope = if custom_sort = _jsonapi_config . _sort
62+ scope = if custom_sort = _jsonapi_compliable . sorting
16863 custom_sort . call ( scope , att , dir )
16964 else
17065 scope . order ( att => dir )
@@ -179,10 +74,10 @@ def jsonapi_paginate(scope)
17974 size = ( page_param [ :size ] || default_page_size ) . to_i
18075
18176 if size > MAX_PAGE_SIZE
182- raise UnsupportedPageSize , "Requested page size #{ size } is greater than max supported size #{ MAX_PAGE_SIZE } "
77+ raise JSONAPICompliable :: Errors :: UnsupportedPageSize , "Requested page size #{ size } is greater than max supported size #{ MAX_PAGE_SIZE } "
18378 end
18479
185- scope = if custom_pagination = _jsonapi_config . _paginate
80+ scope = if custom_pagination = _jsonapi_compliable . pagination
18681 custom_pagination . call ( scope , number , size )
18782 else
18883 scope . page ( number ) . per ( size )
@@ -193,16 +88,16 @@ def jsonapi_paginate(scope)
19388
19489 def jsonapi_filter ( scope )
19590 param_filters = params [ :filter ] || { }
196- scope = _jsonapi_config . default_filter_scope ( self , scope )
91+ scope = _jsonapi_compliable . default_filter_scope ( self , scope )
19792 param_filters . each_pair do |param_name , param_value |
198- scope = _jsonapi_config . filter_scope ( self , scope , param_name , param_value )
93+ scope = _jsonapi_compliable . filter_scope ( self , scope , param_name , param_value )
19994 end
20095
20196 scope
20297 end
20398
20499 def jsonapi_extra_fields ( scope )
205- _jsonapi_config . _extra_fields . each_pair do |namespace , extra_fields |
100+ _jsonapi_compliable . extra_fields . each_pair do |namespace , extra_fields |
206101 extra_fields . each do |extra_field |
207102 if requested_extra_field? ( namespace , extra_field [ :name ] )
208103 scope = extra_field [ :proc ] . call ( scope )
@@ -311,9 +206,9 @@ def force_includes?
311206
312207 module ClassMethods
313208 def jsonapi ( &blk )
314- config = JsonApiConfig . new
315- config . instance_eval ( &blk )
316- self . _jsonapi_config = config
209+ dsl = JsonapiCompliable :: DSL . new
210+ dsl . instance_eval ( &blk )
211+ self . _jsonapi_compliable = dsl
317212 end
318213 end
319214 end
0 commit comments