1
1
module JSONAPICompliable
2
- class BadFilter < StandardError ; end
3
- class UnsupportedPageSize < StandardError ; end
4
-
5
2
module Base
6
3
extend ActiveSupport ::Concern
7
4
include Deserializable
8
5
9
6
MAX_PAGE_SIZE = 1_000
10
7
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
-
113
8
included do
114
- class_attribute :_jsonapi_config
9
+ class_attribute :_jsonapi_compliable
115
10
116
11
def self . inherited ( klass )
117
- klass . _jsonapi_config = nil
12
+ klass . _jsonapi_compliable = nil
118
13
end
119
14
120
15
before_action :parse_fieldsets!
@@ -141,16 +36,16 @@ def self.call(includes, whitelist)
141
36
def scrub_includes
142
37
return unless params [ :include ]
143
38
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 ] ]
146
41
whitelist ? CompareIncludes . call ( includes , whitelist ) : { }
147
42
end
148
43
149
44
def jsonapi_includes ( scope )
150
45
scrubbed = scrub_includes
151
46
return scope unless scrubbed
152
47
153
- scope = if custom_include = _jsonapi_config . _includes [ :custom_function ]
48
+ scope = if custom_include = _jsonapi_compliable . sideloads [ :custom_function ]
154
49
custom_include . call ( scope , scrubbed )
155
50
else
156
51
scope . includes ( scrubbed )
@@ -164,7 +59,7 @@ def jsonapi_sort(scope)
164
59
dir = sort_param . starts_with? ( '-' ) ? :desc : :asc
165
60
att = sort_param . sub ( '-' , '' ) . to_sym
166
61
167
- scope = if custom_sort = _jsonapi_config . _sort
62
+ scope = if custom_sort = _jsonapi_compliable . sorting
168
63
custom_sort . call ( scope , att , dir )
169
64
else
170
65
scope . order ( att => dir )
@@ -179,10 +74,10 @@ def jsonapi_paginate(scope)
179
74
size = ( page_param [ :size ] || default_page_size ) . to_i
180
75
181
76
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 } "
183
78
end
184
79
185
- scope = if custom_pagination = _jsonapi_config . _paginate
80
+ scope = if custom_pagination = _jsonapi_compliable . pagination
186
81
custom_pagination . call ( scope , number , size )
187
82
else
188
83
scope . page ( number ) . per ( size )
@@ -193,16 +88,16 @@ def jsonapi_paginate(scope)
193
88
194
89
def jsonapi_filter ( scope )
195
90
param_filters = params [ :filter ] || { }
196
- scope = _jsonapi_config . default_filter_scope ( self , scope )
91
+ scope = _jsonapi_compliable . default_filter_scope ( self , scope )
197
92
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 )
199
94
end
200
95
201
96
scope
202
97
end
203
98
204
99
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 |
206
101
extra_fields . each do |extra_field |
207
102
if requested_extra_field? ( namespace , extra_field [ :name ] )
208
103
scope = extra_field [ :proc ] . call ( scope )
@@ -311,9 +206,9 @@ def force_includes?
311
206
312
207
module ClassMethods
313
208
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
317
212
end
318
213
end
319
214
end
0 commit comments