[dry-schema] Filter for each element in array

Hello!

I was wondering if I can combine filter with each? For example imagine that the schema receives an array looking like this [“09”, “12”, “2019”]. Before casting that to date by using a custom type I’d like to verify that the array size is 3 and that each element is an int disguised as a string. I was thinking something like this optional(:date).filter(size?: 3, each?: { format?: /\A\d+\Z/ }), but that doesn’t work. On the other hand just chaining .each separately (optional(:date).filter(size?: 3).each(format?: /\A\d+\Z/)) causes it to be evaluated after type cast.

Yes you can do this:

optional(:date)
  .filter(:array, size?: 3) { each(format?: /\A\d+\Z/) }
  .value(...)
1 Like

Works like a charm, thank you!

1 Like

This appears to no longer work. Was this behavior changed, or is this a regression? Or maybe I am doing something wrong?

schema = Dry::Schema.Params do
  optional(:date)
    .filter(:array, size?: 3) { each(format?: /\A\d+\Z/) }
    .value(array[:string])
end

schema.({ date: ["1684964902", "", "1684965059"] })
#<Dry::Schema::Result{:date=>["1684964902", "", "1684965059"]} errors={:date=>{1=>["is in invalid format"]}} path=[]>