I try to create a type which accepts decimal numbers in string with thousand separators
Here is the code I figured after digging the source:
# Usage
# In a controller...
def parsed_params
ParsedParams.new(params.to_unsafe_h)
end
# Definition
class ParsedParams < ::Dry::Struct
# This class requires hash with symbol keys...
# or hash with indifferent access
constructor_type(:schema)
module Types
include ::Dry::Types.module
end
class ListingAttributes < ::Dry::Struct
# This class requires hash with symbol keys...
# or hash with indifferent access
constructor_type(:schema)
module Types
include ::Dry::Types.module
SmartDecimal = Types::Decimal.constructor do |value|
# `BigDecimal` method raise error for blank values
next nil if value.blank?
# `tr` is faster
# https://github.com/JuanitoFatas/fast-ruby#stringgsub-vs-stringtr-code
BigDecimal(value.is_a?(::String) ? value.tr("^0-9", "") : value)
end
end
# Only attributes to be validated are defined here
attribute(
:city_id,
Types::Coercible::String,
)
attribute(
:is_rental,
Types::Form::Bool,
)
attribute(
:price,
Types::SmartDecimal,
)
end
attribute(
:locale,
Types::Coercible::String,
)
attribute(
:listing_attributes,
ListingAttributes,
)
# See predicates that can be used at
# http://dry-rb.org/gems/dry-validation/
InputSchema = ::Dry::Validation.Schema do
required(:locale).filled
required(:listing_attributes).schema do
required(:city_id).filled
required(:is_rental).filled
# can be empty
required(:price)
end
end
end
But I found a page about custom type from the doc recently
And wonder if there is an “official” way to define custom type (with custom constructor)