|
1 | 1 | # StructuredParams |
2 | 2 |
|
3 | | -StructuredParams is a Ruby gem that provides type-safe parameter validation and casting for Rails applications. It extends ActiveModel's type system to handle nested objects and arrays with automatic Strong Parameters integration. |
4 | | - |
5 | 3 | English | [日本語](README_ja.md) |
6 | 4 |
|
7 | | -## Features |
| 5 | +**Type-safe API parameter validation and form objects for Rails** |
| 6 | + |
| 7 | +StructuredParams solves these challenges: |
| 8 | + |
| 9 | +- **API endpoints**: Type checking, validation, and automatic casting of request parameters |
| 10 | +- **Form objects**: Validation and conversion of complex form inputs to models |
| 11 | + |
| 12 | +Built on ActiveModel, making nested objects and arrays easy to handle. |
8 | 13 |
|
9 | | -- **Type-safe parameter validation** using ActiveModel::Type |
10 | | -- **Nested object support** with automatic casting |
11 | | -- **Array handling** for both primitive types and nested objects |
12 | | -- **Strong Parameters integration** with automatic permit lists |
13 | | -- **ActiveModel compatibility** with validations and serialization |
14 | | -- **Form object pattern support** with Rails form helpers integration |
15 | | -- **Enhanced error handling** with flat and structured formats |
16 | | -- **RBS type definitions** for better development experience |
| 14 | +## Key Features |
| 15 | + |
| 16 | +- ✅ **API Parameter Validation** - Type-safe request validation |
| 17 | +- ✅ **Form Objects** - Encapsulate complex form logic |
| 18 | +- ✅ **Nested Structure Support** - Automatic casting for objects and arrays |
| 19 | +- ✅ **Strong Parameters Integration** - Auto-generate permit lists |
| 20 | +- ✅ **ActiveModel Compatible** - Support for validations, serialization, and other standard features |
| 21 | +- ✅ **RBS Type Definitions** - Type-safe development experience |
17 | 22 |
|
18 | 23 | ## Quick Start |
19 | 24 |
|
20 | 25 | ```ruby |
21 | | -# 1. Install the gem |
| 26 | +# Installation |
22 | 27 | gem 'structured_params' |
23 | 28 |
|
24 | | -# 2. Register types in initializer |
| 29 | +# Initialize |
25 | 30 | StructuredParams.register_types |
| 31 | +``` |
| 32 | + |
| 33 | +### 1. API Parameter Validation |
26 | 34 |
|
27 | | -# 3. Define parameter classes |
| 35 | +```ruby |
28 | 36 | class UserParams < StructuredParams::Params |
29 | 37 | attribute :name, :string |
30 | 38 | attribute :age, :integer |
31 | | - attribute :address, :object, value_class: AddressParams |
32 | | - attribute :hobbies, :array, value_class: HobbyParams |
33 | 39 |
|
34 | 40 | validates :name, presence: true |
35 | 41 | validates :age, numericality: { greater_than: 0 } |
36 | 42 | end |
37 | 43 |
|
38 | | -# 4. Use in controllers (API) |
| 44 | +# Use in API controller |
39 | 45 | def create |
40 | | - user_params = UserParams.new(params) |
| 46 | + permitted = UserParams.permit(params, require: false) |
| 47 | + user_params = UserParams.new(permitted) |
41 | 48 |
|
42 | 49 | if user_params.valid? |
43 | 50 | User.create!(user_params.attributes) |
44 | 51 | else |
45 | | - render json: { errors: user_params.errors.to_hash(false, structured: true) } |
| 52 | + render json: { errors: user_params.errors }, status: :unprocessable_entity |
46 | 53 | end |
47 | 54 | end |
| 55 | +``` |
48 | 56 |
|
49 | | -# 5. Use as Form Objects (View Integration) |
| 57 | +### 2. Form Object |
50 | 58 |
|
51 | | -# Define a Form Object class |
| 59 | +```ruby |
52 | 60 | class UserRegistrationForm < StructuredParams::Params |
53 | 61 | attribute :name, :string |
54 | 62 | attribute :email, :string |
55 | | - attribute :password, :string |
| 63 | + attribute :terms_accepted, :boolean |
56 | 64 |
|
57 | | - validates :name, presence: true |
58 | | - validates :email, format: { with: URI::MailTo::EMAIL_REGEXP } |
| 65 | + validates :name, :email, presence: true |
| 66 | + validates :terms_accepted, acceptance: true |
59 | 67 | end |
60 | 68 |
|
61 | | -# Use in controllers |
| 69 | +# Use in controller |
62 | 70 | def create |
63 | | - @form = UserRegistrationForm.new(UserRegistrationForm.permit(params)) |
| 71 | + form = UserRegistrationForm.new(UserRegistrationForm.permit(params)) |
64 | 72 |
|
65 | | - if @form.valid? |
66 | | - User.create!(@form.attributes) |
67 | | - redirect_to user_path |
| 73 | + if form.valid? |
| 74 | + User.create!(form.attributes) |
| 75 | + redirect_to root_path |
68 | 76 | else |
69 | 77 | render :new |
70 | 78 | end |
71 | 79 | end |
72 | | - |
73 | | -# Use in views |
74 | | -<%= form_with model: @form, url: users_path do |f| %> |
75 | | - <%= f.text_field :name %> |
76 | | - <%= f.email_field :email %> |
77 | | - <%= f.password_field :password %> |
78 | | -<% end %> |
79 | 80 | ``` |
80 | 81 |
|
81 | 82 | ## Documentation |
|
84 | 85 | - **[Basic Usage](docs/basic-usage.md)** - Parameter classes, nested objects, and arrays |
85 | 86 | - **[Validation](docs/validation.md)** - Using ActiveModel validations with nested structures |
86 | 87 | - **[Strong Parameters](docs/strong-parameters.md)** - Automatic permit list generation |
87 | | -- **[Form Objects](docs/form-objects.md)** - Using as form objects with Rails form helpers |
88 | 88 | - **[Error Handling](docs/error-handling.md)** - Flat and structured error formats |
89 | 89 | - **[Serialization](docs/serialization.md)** - Converting parameters to hashes and JSON |
90 | 90 | - **[Gem Comparison](docs/comparison.md)** - Comparison with typed_params, dry-validation, and reform |
91 | | -- **[Contributing Guide](CONTRIBUTING.md)** - Developer setup and guidelines |
92 | | -
|
93 | | -## For Developers |
94 | 91 |
|
95 | | -If you're interested in contributing to this project, please see [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, RBS generation, testing guidelines, and more. |
96 | 92 |
|
97 | 93 | ## Contributing |
98 | 94 |
|
|
0 commit comments