@@ -28,36 +28,38 @@ def self.post_filter_methods(type)
28
28
# Methods which should not be available in filters until the before filter
29
29
# has completed
30
30
module PostBeforeFilter
31
- def declared ( passed_params , options = { } , declared_params = nil )
31
+ def declared ( passed_params , options = { } , declared_params = nil , params_nested_path = [ ] )
32
32
options = options . reverse_merge ( include_missing : true , include_parent_namespaces : true )
33
33
declared_params ||= optioned_declared_params ( **options )
34
34
35
35
if passed_params . is_a? ( Array )
36
- declared_array ( passed_params , options , declared_params )
36
+ declared_array ( passed_params , options , declared_params , params_nested_path )
37
37
else
38
- declared_hash ( passed_params , options , declared_params )
38
+ declared_hash ( passed_params , options , declared_params , params_nested_path )
39
39
end
40
40
end
41
41
42
42
private
43
43
44
- def declared_array ( passed_params , options , declared_params )
44
+ def declared_array ( passed_params , options , declared_params , params_nested_path )
45
45
passed_params . map do |passed_param |
46
- declared ( passed_param || { } , options , declared_params )
46
+ declared ( passed_param || { } , options , declared_params , params_nested_path )
47
47
end
48
48
end
49
49
50
- def declared_hash ( passed_params , options , declared_params )
50
+ def declared_hash ( passed_params , options , declared_params , params_nested_path )
51
51
declared_params . each_with_object ( passed_params . class . new ) do |declared_param , memo |
52
52
if declared_param . is_a? ( Hash )
53
53
declared_param . each_pair do |declared_parent_param , declared_children_params |
54
+ params_nested_path_dup = params_nested_path . dup
55
+ params_nested_path_dup << declared_parent_param . to_s
54
56
next unless options [ :include_missing ] || passed_params . key? ( declared_parent_param )
55
57
56
58
passed_children_params = passed_params [ declared_parent_param ] || passed_params . class . new
57
59
memo_key = optioned_param_key ( declared_parent_param , options )
58
60
59
- memo [ memo_key ] = handle_passed_param ( declared_parent_param , passed_children_params ) do
60
- declared ( passed_children_params , options , declared_children_params )
61
+ memo [ memo_key ] = handle_passed_param ( passed_children_params , params_nested_path_dup ) do
62
+ declared ( passed_children_params , options , declared_children_params , params_nested_path_dup )
61
63
end
62
64
end
63
65
else
@@ -77,19 +79,34 @@ def declared_hash(passed_params, options, declared_params)
77
79
end
78
80
end
79
81
80
- def handle_passed_param ( declared_param , passed_children_params , &_block )
81
- should_be_empty_array? ( declared_param , passed_children_params ) ? [ ] : yield
82
+ def handle_passed_param ( passed_children_params , params_nested_path , &_block )
83
+ if should_be_empty_hash? ( passed_children_params , params_nested_path )
84
+ { }
85
+ elsif should_be_empty_array? ( passed_children_params , params_nested_path )
86
+ [ ]
87
+ else
88
+ yield
89
+ end
82
90
end
83
91
84
- def should_be_empty_array? ( declared_param , passed_children_params )
85
- declared_param_is_array? ( declared_param ) && passed_children_params . empty?
92
+ def should_be_empty_array? ( passed_children_params , params_nested_path )
93
+ passed_children_params . empty? && declared_param_is_array? ( params_nested_path )
86
94
end
87
95
88
- def declared_param_is_array? ( declared_param )
89
- key = declared_param . to_s
96
+ def declared_param_is_array? ( params_nested_path )
97
+ key = route_options_params_key ( params_nested_path )
90
98
route_options_params [ key ] && route_options_params [ key ] [ :type ] == 'Array'
91
99
end
92
100
101
+ def should_be_empty_hash? ( passed_children_params , params_nested_path )
102
+ passed_children_params . empty? && declared_param_is_hash? ( params_nested_path )
103
+ end
104
+
105
+ def declared_param_is_hash? ( params_nested_path )
106
+ key = route_options_params_key ( params_nested_path )
107
+ route_options_params [ key ] && route_options_params [ key ] [ :type ] == 'Hash'
108
+ end
109
+
93
110
def route_options_params
94
111
options [ :route_options ] [ :params ] || { }
95
112
end
@@ -98,6 +115,12 @@ def optioned_param_key(declared_param, options)
98
115
options [ :stringify ] ? declared_param . to_s : declared_param . to_sym
99
116
end
100
117
118
+ def route_options_params_key ( params_nested_path )
119
+ key = params_nested_path [ 0 ]
120
+ key += '[' + params_nested_path [ 1 ..-1 ] . join ( '][' ) + ']' if params_nested_path . size > 1
121
+ key
122
+ end
123
+
101
124
def optioned_declared_params ( **options )
102
125
declared_params = if options [ :include_parent_namespaces ]
103
126
# Declared params including parent namespaces
0 commit comments