If you want to use this with dry-validation then you may want to check out a less-known feature - negating a predicate (I probably never documented it anywhere, oops). So here it goes:
Dry::Validation.Schema do
required(:name).filled {
str? & format?(/some-regex/) & format?(/other-regex/).not
}
end
This should work just fine, but it hasn’t been tested a lot, but feel free to try this out and lemme know if it’s what you need.
Piotr, negation is exactly what I was looking for, thanks a lot. Things now work as expected:
$ pry
[1] pry(main)> require 'dry-types'; require 'dry-validation'
true
[2] pry(main)> class Member < Dry::Types::Value
[2] pry(main)* attribute :name, Types::Strict::String.constrained(min_size: 6)
[2] pry(main)* end
Member < Dry::Types::Value
[3] pry(main)> foo = Member.new name: ' John '
{
:name => " John "
}
[4] pry(main)> MemberSchema = Dry::Validation.Schema do
[4] pry(main)* required(:name).filled do
[4] pry(main)* str? & format?(/\A([[:alpha:]][\.\- \w]{4,}\w)\z/) & format?(/\s{2,}/).not
[4] pry(main)* end
[4] pry(main)* end;
[5] pry(main)> MemberSchema.call(foo.to_h).inspect
"#<Dry::Validation::Result output={:name=>\" John \"} messages={:name=>[\"is in invalid format\"]}>"
[6] pry(main)> q = MemberSchema.call(foo.to_h)
{
:name => " John "
}
[7] pry(main)> q.messages
{
:name => [
[0] "is in invalid format"
]
}
[8] pry(main)> exit
$
Now, if I may ask a bonus question: after having read through the doc for error messages, it’s not clear to me if and how one can tell which constraint was violated. For instance, in the example I’d been poking along with, would I be able to have separate error messages for “not long enough or invalid characters” (not matching the first regex) separately from “redundant spaces” (invalidly matching the second)?
Unfortunately there’s no support for negated rules in error messages. You gotta provide custom messages in the yaml file and that should work for now. Just define a custom predicate name and add a message for it.