@@ -7,115 +7,9 @@ module Base
77
88 included do
99 class_attribute :_jsonapi_compliable
10-
11- def self . inherited ( klass )
12- klass . _jsonapi_compliable = nil
13- end
14-
1510 before_action :parse_fieldsets!
1611 end
1712
18- # Private to module
19- class CompareIncludes
20- def self . call ( includes , whitelist )
21- { } . tap do |valid |
22- includes . to_hash . each_pair do |key , sub_hash |
23- if whitelist [ key ]
24- valid [ key ] = CompareIncludes . call ( sub_hash , whitelist [ key ] )
25- end
26- end
27- end
28- end
29- end
30-
31- # Converts include params like foo.bar,baz
32- # to AMS-compliant
33- # {foo: {bar: {}}, baz: {}}
34- #
35- # Ensures they are part of the whitelist
36- def scrub_includes
37- return unless params [ :include ]
38-
39- includes = _jsonapi_compliable . parse_includes ( params [ :include ] )
40- whitelist = _jsonapi_compliable . sideloads [ :whitelist ] [ params [ :action ] ]
41- whitelist ? CompareIncludes . call ( includes , whitelist ) : { }
42- end
43-
44- def jsonapi_includes ( scope )
45- scrubbed = scrub_includes
46- return scope unless scrubbed
47-
48- scope = if custom_include = _jsonapi_compliable . sideloads [ :custom_function ]
49- custom_include . call ( scope , scrubbed )
50- else
51- scope . includes ( scrubbed )
52- end
53-
54- scope
55- end
56-
57- def jsonapi_sort ( scope )
58- sort_param = params [ :sort ] || 'id'
59- dir = sort_param . starts_with? ( '-' ) ? :desc : :asc
60- att = sort_param . sub ( '-' , '' ) . to_sym
61-
62- scope = if custom_sort = _jsonapi_compliable . sorting
63- custom_sort . call ( scope , att , dir )
64- else
65- scope . order ( att => dir )
66- end
67-
68- scope
69- end
70-
71- def jsonapi_paginate ( scope )
72- page_param = params [ :page ] || { }
73- number = ( page_param [ :number ] || default_page_number ) . to_i
74- size = ( page_param [ :size ] || default_page_size ) . to_i
75-
76- if size > MAX_PAGE_SIZE
77- raise JSONAPICompliable ::Errors ::UnsupportedPageSize , "Requested page size #{ size } is greater than max supported size #{ MAX_PAGE_SIZE } "
78- end
79-
80- scope = if custom_pagination = _jsonapi_compliable . pagination
81- custom_pagination . call ( scope , number , size )
82- else
83- scope . page ( number ) . per ( size )
84- end
85-
86- scope
87- end
88-
89- def jsonapi_filter ( scope )
90- param_filters = params [ :filter ] || { }
91- scope = _jsonapi_compliable . default_filter_scope ( self , scope )
92- param_filters . each_pair do |param_name , param_value |
93- scope = _jsonapi_compliable . filter_scope ( self , scope , param_name , param_value )
94- end
95-
96- scope
97- end
98-
99- def jsonapi_extra_fields ( scope )
100- _jsonapi_compliable . extra_fields . each_pair do |namespace , extra_fields |
101- extra_fields . each do |extra_field |
102- if requested_extra_field? ( namespace , extra_field [ :name ] )
103- scope = extra_field [ :proc ] . call ( scope )
104- end
105- end
106- end
107-
108- scope
109- end
110-
111- def requested_extra_field? ( namespace , field )
112- if namespaced = params [ :extra_fields ] . try ( :[] , namespace )
113- namespaced . include? ( field )
114- else
115- false
116- end
117- end
118-
11913 def default_page_number
12014 1
12115 end
@@ -130,44 +24,29 @@ def jsonapi_scope(scope,
13024 paginate : true ,
13125 extra_fields : true ,
13226 sort : true )
133- scope = jsonapi_filter ( scope ) if filter
134- scope = jsonapi_extra_fields ( scope ) if extra_fields
135- scope = jsonapi_includes ( scope ) if includes
136- scope = jsonapi_sort ( scope ) if sort
137- scope = jsonapi_paginate ( scope ) if paginate
27+ scope = JSONAPICompliable ::Scope ::DefaultFilter . new ( self , scope ) . apply
28+ scope = JSONAPICompliable ::Scope ::Filter . new ( self , scope ) . apply if filter
29+ scope = JSONAPICompliable ::Scope ::ExtraFields . new ( self , scope ) . apply if extra_fields
30+ scope = JSONAPICompliable ::Scope ::Sideload . new ( self , scope ) . apply if includes
31+ scope = JSONAPICompliable ::Scope ::Sort . new ( self , scope ) . apply if sort
32+ scope = JSONAPICompliable ::Scope ::Paginate . new ( self , scope ) . apply if paginate
13833 scope
13934 end
14035
141- def fieldset ( name )
142- params [ name ] . to_unsafe_hash . deep_symbolize_keys
143- end
144-
145- def fieldset? ( name )
146- params [ name ] . present?
147- end
148-
14936 def parse_fieldsets!
150- parse_fieldset! ( :fields )
151- parse_fieldset! ( :extra_fields )
152- end
153-
154- def parse_fieldset! ( name )
155- return unless params [ name ]
156-
157- params [ name ] . each_pair do |key , value |
158- params [ name ] [ key ] = value . split ( ',' ) . map ( &:to_sym )
159- end
37+ Util ::FieldParams . parse! ( params , :fields )
38+ Util ::FieldParams . parse! ( params , :extra_fields )
16039 end
16140
16241 # * Eager loads whitelisted includes
16342 # * Merges opts and ams_default_options
16443 def render_ams ( scope , opts = { } )
16544 scope = jsonapi_scope ( scope ) if scope . is_a? ( ActiveRecord ::Relation )
16645 options = default_ams_options
167- options [ :include ] = forced_includes || scrub_includes
46+ options [ :include ] = forced_includes || Util :: IncludeParams . scrub ( self )
16847 options [ :json ] = scope
169- options [ :fields ] = fieldset ( :fields ) if fieldset? ( :fields )
170- options [ :extra_fields ] = fieldset ( :extra_fields ) if fieldset? ( :extra_fields )
48+ options [ :fields ] = Util :: FieldParams . fieldset ( params , :fields ) if params [ :fields ]
49+ options [ :extra_fields ] = Util :: FieldParams . fieldset ( params , :extra_fields ) if params [ :extra_fields ]
17150
17251 options . merge! ( opts )
17352 render ( options )
@@ -211,5 +90,5 @@ def jsonapi(&blk)
21190 self . _jsonapi_compliable = dsl
21291 end
21392 end
214- end
93+ end
21594end
0 commit comments