Module: Railsmith::BaseService::TypeCoercion

Defined in:
lib/railsmith/base_service/type_coercion.rb

Overview

Handles automatic type conversion for declared inputs.

Supported types and their coercion behaviour:

String     → value.to_s
Integer    → Integer(value)   — strict; "abc" raises CoercionError
Float      → Float(value)     — strict
BigDecimal → BigDecimal(value.to_s)
:boolean   → true/false; raises CoercionError for unrecognised values
Date       → Date.parse(value.to_s)
DateTime   → DateTime.parse(value.to_s)
Time       → Time.parse(value.to_s)
Symbol     → value.to_sym
Array      → Array(value)     — wraps non-arrays
Hash       → passthrough; raises CoercionError if not hash-like

Custom coercions can be registered via Railsmith::Configuration:

Railsmith.configure do |c|
  c.register_coercion(:money, ->(v) { Money.new(v) })
end

Defined Under Namespace

Classes: CoercionError

Constant Summary collapse

BUILTIN_COERCIONS =
{
  String => lambda(&:to_s),
  Integer => ->(v) { Integer(v) },
  Float => ->(v) { Float(v) },
  Symbol => lambda(&:to_sym),
  Array => ->(v) { Array(v) },
  Hash => lambda { |v|
    raise TypeError, "expected Hash" unless v.is_a?(Hash)

    v
  },
  :boolean => lambda { |v|
    return true  if [true,  "true",  "1", 1].include?(v)
    return false if [false, "false", "0", 0].include?(v)

    raise ArgumentError, "unrecognised boolean value"
  }
}.freeze
LAZY_COERCIONS =

Lazily-resolved coercions for types that may not be loaded at require time.

{
  "Date" => -> { ->(v) { Date.parse(v.to_s) } },
  "DateTime" => -> { ->(v) { DateTime.parse(v.to_s) } },
  "Time" => -> { ->(v) { Time.parse(v.to_s) } },
  "BigDecimal" => -> { ->(v) { BigDecimal(v.to_s) } }
}.freeze

Class Method Summary collapse

Class Method Details

.coerce(field, value, type) ⇒ Object

Coerce value to type for the named field. Returns value unchanged when it is already the right type, or when no coercion is defined for the type. Returns nil unchanged (callers handle required-nil separately).

Raises:



73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/railsmith/base_service/type_coercion.rb', line 73

def coerce(field, value, type)
  return value if value.nil?
  return value if already_correct_type?(value, type)

  coercer = find_coercer(type)
  return value unless coercer

  coercer.call(value)
rescue CoercionError
  raise
rescue StandardError
  raise CoercionError.new(field, type, value)
end