Class: Treaty::Attribute::Option::Modifiers::CastModifier
- Defined in:
- lib/treaty/attribute/option/modifiers/cast_modifier.rb
Overview
Converts attribute values between different types automatically.
## Usage Examples
Simple mode:
string :created_at, cast: :datetime
datetime :timestamp, cast: :string
integer :active, cast: :boolean
Advanced mode with custom error message:
string :created_at, cast: {
to: :datetime,
message: "Invalid date format"
}
## Use Cases
-
**Request type conversion**: “‘ruby request do
string :created_at, cast: :datetimeend # Input: { created_at: “2024-01-15T10:30:00Z” } # Service receives: { created_at: DateTime object } “‘
-
**Response type conversion**: “‘ruby response 200 do
datetime :created_at, cast: :stringend # Service returns: { created_at: DateTime object } # Output: { created_at: “2024-01-15T10:30:00Z” } “‘
-
**Unix timestamp conversion**: “‘ruby integer :timestamp, cast: :datetime datetime :created_at, cast: :integer “`
## Supported Conversions
### From Integer
-
integer -> string: Converts to string representation
-
integer -> boolean: 0 = false, non-zero = true
-
integer -> date: Treats as Unix timestamp, converts to date
-
integer -> time: Treats as Unix timestamp
-
integer -> datetime: Treats as Unix timestamp, converts to datetime
### From String
-
string -> integer: Parses integer from string
-
string -> boolean: Parses truthy/falsy strings (true/false, yes/no, 1/0, on/off)
-
string -> date: Parses date string
-
string -> time: Parses time string
-
string -> datetime: Parses datetime string (ISO8601, RFC3339, etc.)
### From Boolean
-
boolean -> string: Converts to “true” or “false”
-
boolean -> integer: true = 1, false = 0
### From Date
-
date -> string: Converts to ISO8601 format
-
date -> integer: Converts to Unix timestamp
-
date -> time: Converts to Time at midnight
-
date -> datetime: Converts to DateTime at midnight
### From Time
-
time -> string: Converts to ISO8601 format
-
time -> integer: Converts to Unix timestamp
-
time -> date: Converts to Date
-
time -> datetime: Converts to DateTime
### From DateTime
-
datetime -> string: Converts to ISO8601 format
-
datetime -> integer: Converts to Unix timestamp
-
datetime -> date: Converts to Date
-
datetime -> time: Converts to Time
## Important Notes
-
Cast option only works with scalar types (integer, string, boolean, date, time, datetime)
-
Array and Object types are not supported for casting
-
Casting to the same type is allowed (no-op)
-
Nil values are not transformed (handled by RequiredValidator)
-
All conversion errors are caught and re-raised as Validation errors
## Error Handling
If conversion fails (e.g., invalid date string, non-numeric string to integer), the error is caught and converted to a Treaty::Exceptions::Validation error.
## Advanced Mode
Schema format: ‘{ to: :target_type, message: “Custom error” }` Note: Uses `:to` key instead of the default `:is` key.
Constant Summary collapse
- ALLOWED_CAST_TYPES =
Types that support casting (scalar types only)
%i[integer string boolean date time datetime].freeze
Instance Method Summary collapse
-
#transform_value(value) ⇒ Object
Applies type conversion to the value Skips conversion for nil values (handled by RequiredValidator).
-
#validate_schema! ⇒ void
Validates that cast option is correctly configured.
Methods inherited from Base
#initialize, #target_name, #transforms_name?, #validate_value!
Constructor Details
This class inherits a constructor from Treaty::Attribute::Option::Base
Instance Method Details
#transform_value(value) ⇒ Object
Applies type conversion to the value Skips conversion for nil values (handled by RequiredValidator)
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/treaty/attribute/option/modifiers/cast_modifier.rb', line 166 def transform_value(value) # rubocop:disable Metrics/MethodLength return value if value.nil? # Cast doesn't modify nil, required validator handles it. target_type = option_value conversion_lambda = conversion_matrix.dig(@attribute_type, target_type) # Call conversion lambda conversion_lambda.call(value:) rescue StandardError => e attributes = { attribute: @attribute_name, from: @attribute_type, to: target_type, value:, error: e. } # Catch all exceptions from conversion execution = (**attributes) || I18n.t( "treaty.attributes.modifiers.cast.conversion_error", **attributes ) raise Treaty::Exceptions::Validation, end |
#validate_schema! ⇒ void
This method returns an undefined value.
Validates that cast option is correctly configured
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/treaty/attribute/option/modifiers/cast_modifier.rb', line 111 def validate_schema! # rubocop:disable Metrics/MethodLength, Metrics/AbcSize # If option_schema is nil, cast is not used for this attribute return if @option_schema.nil? target_type = option_value # Validate that target type is a Symbol unless target_type.is_a?(Symbol) raise Treaty::Exceptions::Validation, I18n.t( "treaty.attributes.modifiers.cast.invalid_type", attribute: @attribute_name, type: target_type.class ) end # Validate that source type supports casting unless ALLOWED_CAST_TYPES.include?(@attribute_type) raise Treaty::Exceptions::Validation, I18n.t( "treaty.attributes.modifiers.cast.source_not_supported", attribute: @attribute_name, source_type: @attribute_type, allowed: ALLOWED_CAST_TYPES.join(", ") ) end # Validate that target type is allowed unless ALLOWED_CAST_TYPES.include?(target_type) raise Treaty::Exceptions::Validation, I18n.t( "treaty.attributes.modifiers.cast.target_not_supported", attribute: @attribute_name, target_type:, allowed: ALLOWED_CAST_TYPES.join(", ") ) end # Validate that conversion from source to target is supported return if conversion_supported?(@attribute_type, target_type) raise Treaty::Exceptions::Validation, I18n.t( "treaty.attributes.modifiers.cast.conversion_not_supported", attribute: @attribute_name, from: @attribute_type, to: target_type ) end |