When specifying a schema using dry-validations
, I can do something like this to check for a particular type of UUID:
required(:uuid).value(:string, :uuid_v4?)
This is invoking the uuid_v4?
predicate provided by dry-logic
. I would like to simplify this by creating a custom type to use instead. Something like:
required(:uuid).filled(My::Types::ContactUuid)
However, I am having trouble creating this custom type. The dry-types
constraints docs say that “Under the hood it uses dry-logic
and all of its predicates are supported.” However, the examples given only show predicates that take an argument:
string = Types::String.constrained(min_size: 3)
If the predicate does not take an argument, like uuid_v4
(and many other boolean-like predicates), then how can it be used in the constrained
method?
I tried everything I can think of and the only thing that works is to pass a dummy argument. I use nil
here, but literally anything should work.
module My
module Types
include Dry.Types()
ContactUuid = Types::String.constrained(uuid_v4: nil)
end
end
Is this expected behavior? It appears to be so from the implementation of self.Rule
:
# frozen_string_literal: true
module Dry
# Helper methods for constraint types
#
# @api public
module Types
# @param [Hash] options
#
# @return [Dry::Logic::Rule]
#
# @api public
def self.Rule(options)
rule_compiler.(
options.map { |key, val|
::Dry::Logic::Rule::Predicate.build(
::Dry::Logic::Predicates[:"#{key}?"]
).curry(val).to_ast
}
).reduce(:and)
end
# @return [Dry::Logic::RuleCompiler]
#
# @api private
def self.rule_compiler
@rule_compiler ||= ::Dry::Logic::RuleCompiler.new(::Dry::Logic::Predicates)
end
end
end
Am I missing something? Is there a better way?
Thank you!