@@ -24,6 +24,45 @@ class UserParams < StructuredParams::Params
2424end
2525```
2626
27+ ## Validate Raw Input (` validates_raw ` )
28+
29+ Use ` validates_raw ` to validate the original input value before type casting.
30+
31+ ``` ruby
32+ class UserParams < StructuredParams ::Params
33+ attribute :age , :integer
34+
35+ validates_raw :age , format: { with: /\A\d +\z / , message: ' must be numeric string' }
36+ end
37+
38+ params = UserParams .new (age: ' 12x' )
39+ params.valid? # => false
40+ params.errors.to_hash # => { age: ["must be numeric string"] }
41+ ```
42+
43+ ` validates_raw ` uses ` *_before_type_cast ` internally, then remaps errors back to the original attribute.
44+ So ` errors[:age_before_type_cast] ` remains empty in normal usage.
45+
46+ ### Combining ` validates_raw ` and ` validates ` on the same attribute
47+
48+ You can use both on the same attribute.
49+
50+ ``` ruby
51+ class UserParams < StructuredParams ::Params
52+ attribute :score , :integer
53+
54+ validates_raw :score , format: { with: /\A\d +\z / , message: ' must be numeric string' }
55+ validates :score , numericality: { greater_than_or_equal_to: 0 }
56+ end
57+
58+ params = UserParams .new (score: ' abc' )
59+ params.valid? # => false
60+ params.errors[:score ]
61+ # => includes both "must be numeric string" and "is not a number"
62+ ```
63+
64+ When both validations fail, both messages are added to the same attribute (` :score ` ).
65+
2766## Nested Validation
2867
2968Validation automatically cascades to nested objects and arrays:
0 commit comments