Skip to content

Add type coercion for property assignments #146

@sergiobayona

Description

@sergiobayona

Related to #137

Issue #137 identified that integer properties coerce string values (e.g., "30"30). However, investigation reveals that no coercion is currently happening - values are stored as-is and validations incorrectly pass for mismatched types.

Current Behavior

class TestModel
  include EasyTalk::Model
  define_schema do
    property :name, String
    property :count, Integer
  end
end

model = TestModel.new(name: 30, count: "42")
model.name   # => 30 (Integer, not coerced to String)
model.count  # => "42" (String, not coerced to Integer)
model.valid? # => true (incorrectly passes!)

Proposed Coercions

Type Input Coerced Output
String 30 (Integer) "30"
String 3.14 (Float) "3.14"
String :hello (Symbol) "hello"
String true/false "true"/"false"
Integer "42" (String) 42
Integer 42.9 (Float) 42 (truncate)
Float "3.14" (String) 3.14
Float 42 (Integer) 42.0
BigDecimal "123.45" (String) BigDecimal("123.45")
BigDecimal 123.45 (Float) BigDecimal("123.45")
T::Boolean "true", "1", 1 true
T::Boolean "false", "0", 0 false
Date "2024-01-15" (String) Date.parse("2024-01-15")
Time "2024-01-15T10:30:00Z" Time.parse(...)
DateTime "2024-01-15T10:30:00Z" DateTime.parse(...)
Symbol "active" (String) :active
Array Single value [value] (wrap in array)

Design Considerations

  1. Fail on impossible coercion - "abc" → Integer should fail validation, not coerce to 0
  2. Configurable - Add EasyTalk.configure { |c| c.coerce_types = true } (default: true for Pydantic-like behavior)
  3. Coerce on assignment - Happens in the attribute writer, before validation
  4. Respect nilable types - nil should pass through without coercion for T.nilable types

Implementation Notes

  • Coercion should happen in EasyTalk::Model when defining attribute accessors
  • Consider creating a TypeCoercer class with type-specific coercion logic
  • Invalid coercions (e.g., "abc" to Integer) should leave value as-is and let validation fail

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpriority: highHigh value features or important fixes

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions