-
Notifications
You must be signed in to change notification settings - Fork 0
Add comparison document for StructuredParams and similar gems #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -20,7 +20,7 @@ StructuredParams は、Rails アプリケーションでタイプセーフなパ | |||||
| # 1. gem をインストール | ||||||
| gem 'structured_params' | ||||||
|
|
||||||
| # 2. イニ��ャライザで型を登録 | ||||||
| # 2. イニシャライザで型を登録 | ||||||
| StructuredParams.register_types | ||||||
|
|
||||||
| # 3. パラメータクラスを定義 | ||||||
|
|
@@ -49,10 +49,11 @@ end | |||||
|
|
||||||
| - **[インストールとセットアップ](docs/installation.md)** - StructuredParams の始め方 | ||||||
| - **[基本的な使用方法](docs/basic-usage.md)** - パラメータクラス、ネストオブジェクト、配列 | ||||||
| - **[バリデーション](docs/validation.md)** - ネスト構造での ActiveModel バリデーション | ||||||
| - **[Strong Parameters](docs/strong-parameters.md)** - 自動 permit リスト生成 | ||||||
| - **[バリデーション](docs/validation.md)** - ネスト構造でのActiveModelバリデーション使用 | ||||||
|
||||||
| - **[バリデーション](docs/validation.md)** - ネスト構造でのActiveModelバリデーション使用 | |
| - **[バリデーション](docs/validation.md)** - ネスト構造での ActiveModel バリデーション使用 |
Copilot
AI
Sep 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing space between '自動' and 'permit' for consistency with other entries.
Suggested change
| - **[Strong Parameters](docs/strong-parameters.md)** - 自動permit リスト生成 | |
| - **[Strong Parameters](docs/strong-parameters.md)** - 自動 permit リスト生成 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,220 @@ | ||
| # Comparison with Similar Gems | ||
|
|
||
| This document compares StructuredParams with other parameter handling gems in the Ruby/Rails ecosystem. | ||
|
|
||
| ## Overview Comparison | ||
|
|
||
| | Feature | StructuredParams | typed_params | dry-validation | reform | | ||
| |---------|------------------|--------------|----------------|---------| | ||
| | Type Safety | ✅ ActiveModel::Type | ✅ Built-in types | ✅ Schema validation | ✅ Form objects | | ||
| | Nested Objects | ✅ Native support | ❌ Limited | ✅ Schema nesting | ✅ Composition | | ||
| | Array Handling | ✅ Typed arrays | ❌ Basic arrays | ✅ Array validation | ✅ Collection forms | | ||
| | Strong Parameters | ✅ Auto-generation | ❌ Manual | ❌ Manual | ❌ Manual | | ||
| | ActiveModel Integration | ✅ Full compatibility | ❌ Limited | ❌ None | ✅ Full compatibility | | ||
| | Error Handling | ✅ Flat & structured | ✅ Basic | ✅ Detailed | ✅ ActiveModel errors | | ||
| | RBS Support | ✅ Built-in | ❌ None | ❌ None | ❌ None | | ||
|
|
||
| ## Detailed Comparison | ||
|
|
||
| ### vs. typed_params | ||
|
|
||
| **typed_params** provides basic type casting but lacks advanced features: | ||
|
|
||
| ```ruby | ||
| # typed_params - Basic usage | ||
| class UserController < ApplicationController | ||
| typed_params do | ||
| param :name, type: String, required: true | ||
| param :age, type: Integer | ||
| end | ||
| end | ||
|
|
||
| # StructuredParams - Advanced features | ||
| class UserParams < StructuredParams::Params | ||
| attribute :name, :string | ||
| attribute :age, :integer | ||
| attribute :address, :object, value_class: AddressParams | ||
| attribute :hobbies, :array, value_class: HobbyParams | ||
|
|
||
| validates :name, presence: true | ||
| validates :age, numericality: { greater_than: 0 } | ||
| end | ||
| ``` | ||
|
|
||
| **Advantages of StructuredParams:** | ||
| - Native nested object support | ||
| - Typed array handling | ||
| - Automatic Strong Parameters integration | ||
| - Full ActiveModel validation support | ||
| - Enhanced error handling with structured formats | ||
|
|
||
| ### vs. dry-validation | ||
|
|
||
| **dry-validation** is a powerful validation library but requires more setup: | ||
|
|
||
| ```ruby | ||
| # dry-validation - Schema definition | ||
| UserContract = Dry::Validation.Contract do | ||
| params do | ||
| required(:name).filled(:string) | ||
| required(:age).filled(:integer) | ||
| optional(:address).hash do | ||
| required(:street).filled(:string) | ||
| required(:city).filled(:string) | ||
| end | ||
| end | ||
|
|
||
| rule(:age) { failure('must be positive') if value <= 0 } | ||
| end | ||
|
|
||
| # StructuredParams - Simpler approach | ||
| class UserParams < StructuredParams::Params | ||
| attribute :name, :string | ||
| attribute :age, :integer | ||
| attribute :address, :object, value_class: AddressParams | ||
|
|
||
| validates :name, presence: true | ||
| validates :age, numericality: { greater_than: 0 } | ||
| end | ||
| ``` | ||
|
|
||
| **Advantages of StructuredParams:** | ||
| - More Rails-friendly syntax | ||
| - Built-in Strong Parameters support | ||
| - ActiveModel compatibility for serialization | ||
| - Less boilerplate code | ||
| - Native object composition | ||
|
|
||
| ### vs. reform | ||
|
|
||
| **reform** provides form objects but with different focus: | ||
|
|
||
| ```ruby | ||
| # reform - Form object approach | ||
| class UserForm < Reform::Form | ||
| property :name | ||
| property :age | ||
|
|
||
| collection :addresses do | ||
| property :street | ||
| property :city | ||
| end | ||
|
|
||
| validates :name, presence: true | ||
| end | ||
|
|
||
| # StructuredParams - Parameter object approach | ||
| class UserParams < StructuredParams::Params | ||
| attribute :name, :string | ||
| attribute :age, :integer | ||
| attribute :addresses, :array, value_class: AddressParams | ||
|
|
||
| validates :name, presence: true | ||
| end | ||
| ``` | ||
|
|
||
| **Advantages of StructuredParams:** | ||
| - Focus on parameter handling rather than form rendering | ||
| - Automatic type casting with ActiveModel::Type | ||
| - Built-in Strong Parameters integration | ||
| - Cleaner syntax for API-first applications | ||
| - Better TypeScript/RBS integration | ||
|
|
||
| ## When to Choose StructuredParams | ||
|
|
||
| Choose **StructuredParams** when you need: | ||
|
|
||
| 1. **Type-safe parameter handling** in Rails APIs | ||
| 2. **Complex nested structures** with automatic casting | ||
| 3. **Strong Parameters integration** without manual permit lists | ||
| 4. **ActiveModel compatibility** for validations and serialization | ||
| 5. **Enhanced error handling** with structured formats | ||
| 6. **RBS type definitions** for better development experience | ||
|
|
||
| ## Migration Examples | ||
|
|
||
| ### From typed_params | ||
|
|
||
| ```ruby | ||
| # Before: typed_params | ||
| class UsersController < ApplicationController | ||
| typed_params do | ||
| param :user, type: Hash do | ||
| param :name, type: String, required: true | ||
| param :age, type: Integer | ||
| end | ||
| end | ||
|
|
||
| def create | ||
| # Manual parameter extraction and validation | ||
| end | ||
| end | ||
|
|
||
| # After: StructuredParams | ||
| class UserParams < StructuredParams::Params | ||
| attribute :name, :string | ||
| attribute :age, :integer | ||
|
|
||
| validates :name, presence: true | ||
| end | ||
|
|
||
| class UsersController < ApplicationController | ||
| def create | ||
| user_params = UserParams.new(params[:user]) | ||
| if user_params.valid? | ||
| User.create!(user_params.attributes) | ||
| else | ||
| render json: { errors: user_params.errors.to_hash } | ||
| end | ||
| end | ||
| end | ||
| ``` | ||
|
|
||
| ### From dry-validation | ||
|
|
||
| ```ruby | ||
| # Before: dry-validation | ||
| UserContract = Dry::Validation.Contract do | ||
| params do | ||
| required(:name).filled(:string) | ||
| required(:age).filled(:integer) | ||
| end | ||
| end | ||
|
|
||
| def create | ||
| result = UserContract.call(params[:user]) | ||
| if result.success? | ||
| User.create!(result.to_h) | ||
| else | ||
| render json: { errors: result.errors.to_h } | ||
| end | ||
| end | ||
|
|
||
| # After: StructuredParams | ||
| class UserParams < StructuredParams::Params | ||
| attribute :name, :string | ||
| attribute :age, :integer | ||
|
|
||
| validates :name, presence: true | ||
| end | ||
|
|
||
| def create | ||
| user_params = UserParams.new(params[:user]) | ||
| if user_params.valid? | ||
| User.create!(user_params.attributes) | ||
| else | ||
| render json: { errors: user_params.errors.to_hash } | ||
| end | ||
| end | ||
| ``` | ||
|
|
||
| ## Performance Considerations | ||
|
|
||
| StructuredParams leverages ActiveModel::Type system, which provides: | ||
|
|
||
| - **Efficient type casting** with built-in Rails optimizations | ||
| - **Memory-efficient validation** using ActiveModel's proven patterns | ||
| - **Lazy loading** of nested objects only when accessed | ||
| - **Cached permit lists** for Strong Parameters integration | ||
|
|
||
| For high-throughput APIs, StructuredParams typically performs comparably to or better than manual parameter handling while providing significantly more features and type safety. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The katakana spelling 'イニシャライザ' should be 'イニシャライザー' (with ー) to be more accurate for 'initializer'.