structured_params 0.9.4 → 0.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/lib/structured_params/params.rb +63 -14
- data/lib/structured_params/version.rb +1 -1
- data/sig/structured_params/params.rbs +39 -8
- metadata +5 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 786740a05f9ea27ee5e8b4c5b05aec0c5807fbac8b5995911e94a35f385c4bf4
|
|
4
|
+
data.tar.gz: 13647825c70a9bdfa94f5dcc14a1ae4c6c175bfa75c14e4e89183d89ad422175
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0a4bb67dbe0b7429b07a94c926fc5a1975642992aaee50efdb58e8d9df6c9dd4cca8e7f19e35f2bd0a91c20a23c28940cf30eea27bcfcf062ed9f44b58d35ff6
|
|
7
|
+
data.tar.gz: 5b22220f7d90edf6b47ccadfe27aa0d1f5724388c7ca0976093dd9546936410539102c7336b9e74b7c224ed57816798b3fb5b8c6f2286da0bedc2511e3a367d6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.9.5] - 2026-07-12
|
|
4
|
+
|
|
5
|
+
## What's Changed
|
|
6
|
+
* Refine README and installation copy by @Syati in https://github.com/Syati/structured_params/pull/18
|
|
7
|
+
* Simplify form object params initialization by @Syati in https://github.com/Syati/structured_params/pull/19
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
**Full Changelog**: https://github.com/Syati/structured_params/compare/v0.9.4...v0.9.5
|
|
11
|
+
|
|
3
12
|
## [0.9.4] - 2026-05-02
|
|
4
13
|
|
|
5
14
|
## What's Changed
|
|
@@ -37,7 +37,7 @@ module StructuredParams
|
|
|
37
37
|
# end
|
|
38
38
|
#
|
|
39
39
|
# # In controller:
|
|
40
|
-
# @form = UserRegistrationForm.new(
|
|
40
|
+
# @form = UserRegistrationForm.new(params)
|
|
41
41
|
# if @form.valid?
|
|
42
42
|
# User.create!(@form.attributes)
|
|
43
43
|
# redirect_to user_path
|
|
@@ -50,6 +50,7 @@ module StructuredParams
|
|
|
50
50
|
# <%= f.text_field :name %>
|
|
51
51
|
# <%= f.text_field :email %>
|
|
52
52
|
# <% end %>
|
|
53
|
+
# rubocop:disable Metrics/ClassLength
|
|
53
54
|
class Params
|
|
54
55
|
include ActiveModel::Model
|
|
55
56
|
include ActiveModel::Attributes
|
|
@@ -98,7 +99,7 @@ module StructuredParams
|
|
|
98
99
|
|
|
99
100
|
# Permit parameters with optional require
|
|
100
101
|
#
|
|
101
|
-
# For Form Objects (
|
|
102
|
+
# For Form Objects (explicit manual permit):
|
|
102
103
|
# UserRegistrationForm.permit(params)
|
|
103
104
|
# # equivalent to:
|
|
104
105
|
# params.require(:user_registration).permit(*UserRegistrationForm.permit_attribute_names)
|
|
@@ -132,6 +133,11 @@ module StructuredParams
|
|
|
132
133
|
end
|
|
133
134
|
end
|
|
134
135
|
|
|
136
|
+
#: () -> bool
|
|
137
|
+
def form_class?
|
|
138
|
+
name&.end_with?('Form') || false
|
|
139
|
+
end
|
|
140
|
+
|
|
135
141
|
private
|
|
136
142
|
|
|
137
143
|
# Determine if the specified type is a StructuredParams type
|
|
@@ -156,27 +162,17 @@ module StructuredParams
|
|
|
156
162
|
@errors ||= Errors.new(self)
|
|
157
163
|
end
|
|
158
164
|
|
|
159
|
-
#
|
|
160
|
-
# Form object support methods
|
|
161
|
-
# These methods enable integration with Rails form helpers (form_with, form_for)
|
|
162
|
-
# ========================================
|
|
163
|
-
|
|
164
|
-
# Indicates whether the form object has been persisted to database
|
|
165
|
-
# Always returns false for parameter/form objects
|
|
165
|
+
# Form object support for Rails helpers.
|
|
166
166
|
#: () -> bool
|
|
167
167
|
def persisted?
|
|
168
168
|
false
|
|
169
169
|
end
|
|
170
170
|
|
|
171
|
-
# Returns the primary key value for the model
|
|
172
|
-
# Always returns nil for parameter/form objects
|
|
173
171
|
#: () -> nil
|
|
174
172
|
def to_key
|
|
175
173
|
nil
|
|
176
174
|
end
|
|
177
175
|
|
|
178
|
-
# Returns self for form helpers
|
|
179
|
-
# Required by Rails form helpers to get the model object
|
|
180
176
|
#: () -> self
|
|
181
177
|
def to_model
|
|
182
178
|
self
|
|
@@ -212,7 +208,7 @@ module StructuredParams
|
|
|
212
208
|
def process_input_parameters(params)
|
|
213
209
|
case params
|
|
214
210
|
when ActionController::Parameters
|
|
215
|
-
|
|
211
|
+
process_action_controller_parameters(params)
|
|
216
212
|
when Hash
|
|
217
213
|
# ActiveModel::Attributes can handle both symbol and string keys
|
|
218
214
|
params
|
|
@@ -221,6 +217,58 @@ module StructuredParams
|
|
|
221
217
|
end
|
|
222
218
|
end
|
|
223
219
|
|
|
220
|
+
#: (ActionController::Parameters) -> Hash[untyped, untyped]
|
|
221
|
+
def process_action_controller_parameters(params)
|
|
222
|
+
self.class.permit(params, require: require_nested_parameters?(params)).to_h
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Whether to call params.require(param_key) before permitting.
|
|
226
|
+
#
|
|
227
|
+
# Only ever true for Form-suffixed classes (form_class?); non-Form
|
|
228
|
+
# Params/Parameters subclasses always permit the top level directly.
|
|
229
|
+
#
|
|
230
|
+
# - A value nested under the model's param_key (e.g. params[:user_registration])
|
|
231
|
+
# always wins, even if params were already permitted higher up, since that
|
|
232
|
+
# inner key still needs to be require()'d out.
|
|
233
|
+
# - Otherwise, params that are already permitted, or whose shape looks flat
|
|
234
|
+
# (see flat_parameters?), are used as-is without requiring.
|
|
235
|
+
# - Anything else falls through to true, so params.require raises
|
|
236
|
+
# ActionController::ParameterMissing instead of guessing which keys
|
|
237
|
+
# belong to this form.
|
|
238
|
+
#: (ActionController::Parameters) -> bool
|
|
239
|
+
def require_nested_parameters?(params)
|
|
240
|
+
return false unless self.class.form_class?
|
|
241
|
+
return true if matches_model_name?(params)
|
|
242
|
+
return false if params.permitted?
|
|
243
|
+
return false if flat_parameters?(params)
|
|
244
|
+
|
|
245
|
+
true
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
#: (ActionController::Parameters) -> bool
|
|
249
|
+
def matches_model_name?(params)
|
|
250
|
+
key = self.class.model_name.param_key
|
|
251
|
+
return false unless params.key?(key)
|
|
252
|
+
|
|
253
|
+
params[key].is_a?(ActionController::Parameters)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Only treat params as already-flat attributes when none of the top-level
|
|
257
|
+
# values are themselves nested. A nested value under some other key means
|
|
258
|
+
# the request shape is ambiguous, so we fall through to raising
|
|
259
|
+
# ParameterMissing instead of silently guessing which keys belong here.
|
|
260
|
+
#: (ActionController::Parameters) -> bool
|
|
261
|
+
def flat_parameters?(params)
|
|
262
|
+
return false if params.values.any?(ActionController::Parameters)
|
|
263
|
+
|
|
264
|
+
attribute_keys_present?(params)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
#: (ActionController::Parameters) -> bool
|
|
268
|
+
def attribute_keys_present?(params)
|
|
269
|
+
params.keys.any? { |key| self.class.attribute_types.key?(key.to_s) }
|
|
270
|
+
end
|
|
271
|
+
|
|
224
272
|
# Execute structured parameter validation
|
|
225
273
|
#: () -> void
|
|
226
274
|
def validate_structured_parameters
|
|
@@ -299,4 +347,5 @@ module StructuredParams
|
|
|
299
347
|
end
|
|
300
348
|
end
|
|
301
349
|
end
|
|
350
|
+
# rubocop:enable Metrics/ClassLength
|
|
302
351
|
end
|
|
@@ -36,7 +36,7 @@ module StructuredParams
|
|
|
36
36
|
# end
|
|
37
37
|
#
|
|
38
38
|
# # In controller:
|
|
39
|
-
# @form = UserRegistrationForm.new(
|
|
39
|
+
# @form = UserRegistrationForm.new(params)
|
|
40
40
|
# if @form.valid?
|
|
41
41
|
# User.create!(@form.attributes)
|
|
42
42
|
# redirect_to user_path
|
|
@@ -49,6 +49,7 @@ module StructuredParams
|
|
|
49
49
|
# <%= f.text_field :name %>
|
|
50
50
|
# <%= f.text_field :email %>
|
|
51
51
|
# <% end %>
|
|
52
|
+
# rubocop:disable Metrics/ClassLength
|
|
52
53
|
class Params
|
|
53
54
|
include ActiveModel::Model
|
|
54
55
|
|
|
@@ -84,7 +85,7 @@ module StructuredParams
|
|
|
84
85
|
|
|
85
86
|
# Permit parameters with optional require
|
|
86
87
|
#
|
|
87
|
-
# For Form Objects (
|
|
88
|
+
# For Form Objects (explicit manual permit):
|
|
88
89
|
# UserRegistrationForm.permit(params)
|
|
89
90
|
# # equivalent to:
|
|
90
91
|
# params.require(:user_registration).permit(*UserRegistrationForm.permit_attribute_names)
|
|
@@ -101,6 +102,9 @@ module StructuredParams
|
|
|
101
102
|
# : () -> Hash[Symbol, singleton(::StructuredParams::Params)]
|
|
102
103
|
def self.structured_attributes: () -> Hash[Symbol, singleton(::StructuredParams::Params)]
|
|
103
104
|
|
|
105
|
+
# : () -> bool
|
|
106
|
+
def self.form_class?: () -> bool
|
|
107
|
+
|
|
104
108
|
# Determine if the specified type is a StructuredParams type
|
|
105
109
|
# : (ActiveModel::Type::Value) -> bool
|
|
106
110
|
private def self.structured_params_type?: (ActiveModel::Type::Value) -> bool
|
|
@@ -111,18 +115,13 @@ module StructuredParams
|
|
|
111
115
|
# : () -> ::StructuredParams::Errors
|
|
112
116
|
def errors: () -> ::StructuredParams::Errors
|
|
113
117
|
|
|
114
|
-
#
|
|
115
|
-
# Always returns false for parameter/form objects
|
|
118
|
+
# Form object support for Rails helpers.
|
|
116
119
|
# : () -> bool
|
|
117
120
|
def persisted?: () -> bool
|
|
118
121
|
|
|
119
|
-
# Returns the primary key value for the model
|
|
120
|
-
# Always returns nil for parameter/form objects
|
|
121
122
|
# : () -> nil
|
|
122
123
|
def to_key: () -> nil
|
|
123
124
|
|
|
124
|
-
# Returns self for form helpers
|
|
125
|
-
# Required by Rails form helpers to get the model object
|
|
126
125
|
# : () -> self
|
|
127
126
|
def to_model: () -> self
|
|
128
127
|
|
|
@@ -138,6 +137,38 @@ module StructuredParams
|
|
|
138
137
|
# : (untyped) -> Hash[untyped, untyped]
|
|
139
138
|
def process_input_parameters: (untyped) -> Hash[untyped, untyped]
|
|
140
139
|
|
|
140
|
+
# : (ActionController::Parameters) -> Hash[untyped, untyped]
|
|
141
|
+
def process_action_controller_parameters: (ActionController::Parameters) -> Hash[untyped, untyped]
|
|
142
|
+
|
|
143
|
+
# Whether to call params.require(param_key) before permitting.
|
|
144
|
+
#
|
|
145
|
+
# Only ever true for Form-suffixed classes (form_class?); non-Form
|
|
146
|
+
# Params/Parameters subclasses always permit the top level directly.
|
|
147
|
+
#
|
|
148
|
+
# - A value nested under the model's param_key (e.g. params[:user_registration])
|
|
149
|
+
# always wins, even if params were already permitted higher up, since that
|
|
150
|
+
# inner key still needs to be require()'d out.
|
|
151
|
+
# - Otherwise, params that are already permitted, or whose shape looks flat
|
|
152
|
+
# (see flat_parameters?), are used as-is without requiring.
|
|
153
|
+
# - Anything else falls through to true, so params.require raises
|
|
154
|
+
# ActionController::ParameterMissing instead of guessing which keys
|
|
155
|
+
# belong to this form.
|
|
156
|
+
# : (ActionController::Parameters) -> bool
|
|
157
|
+
def require_nested_parameters?: (ActionController::Parameters) -> bool
|
|
158
|
+
|
|
159
|
+
# : (ActionController::Parameters) -> bool
|
|
160
|
+
def matches_model_name?: (ActionController::Parameters) -> bool
|
|
161
|
+
|
|
162
|
+
# Only treat params as already-flat attributes when none of the top-level
|
|
163
|
+
# values are themselves nested. A nested value under some other key means
|
|
164
|
+
# the request shape is ambiguous, so we fall through to raising
|
|
165
|
+
# ParameterMissing instead of silently guessing which keys belong here.
|
|
166
|
+
# : (ActionController::Parameters) -> bool
|
|
167
|
+
def flat_parameters?: (ActionController::Parameters) -> bool
|
|
168
|
+
|
|
169
|
+
# : (ActionController::Parameters) -> bool
|
|
170
|
+
def attribute_keys_present?: (ActionController::Parameters) -> bool
|
|
171
|
+
|
|
141
172
|
# Execute structured parameter validation
|
|
142
173
|
# : () -> void
|
|
143
174
|
def validate_structured_parameters: () -> void
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: structured_params
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mizuki Yamamoto
|
|
@@ -49,7 +49,9 @@ dependencies:
|
|
|
49
49
|
- - "<"
|
|
50
50
|
- !ruby/object:Gem::Version
|
|
51
51
|
version: '9.0'
|
|
52
|
-
description:
|
|
52
|
+
description: StructuredParams provides typed parameter objects for Rails APIs and
|
|
53
|
+
forms, with nested object and array support, Strong Parameters integration, and
|
|
54
|
+
raw-input validation via validates_raw.
|
|
53
55
|
email:
|
|
54
56
|
- mizuki-y@syati.info
|
|
55
57
|
executables: []
|
|
@@ -101,5 +103,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
101
103
|
requirements: []
|
|
102
104
|
rubygems_version: 3.6.9
|
|
103
105
|
specification_version: 4
|
|
104
|
-
summary:
|
|
106
|
+
summary: Typed parameter objects and form objects for Rails.
|
|
105
107
|
test_files: []
|