Open flash-gordon opened 5 years ago
I've been thinking about it, we could give this a shot, we have better APIs to build this feature now. The only difference would be to use array
instead of each
.
Also needs to support the simple case of
[
"I'm a string",
"I'm another string"
]
There is a way to workaround this until have a final solution?
@CesarOliveira you can define a schema for an array item and have a wrapper that applies it to each item and then merge results into one.
hi @solnic I thought something like that, put a verification inside the match_schema.rb
if is a collection and call the schema for each item, but I thought maybe was something similar done in the gem, thanks for the answer and congrats in the gem as well
Any update on this feature?
@volkanunsal not yet, still scheduled for 2.0.0 though
I guess this is perhaps related to this issue... But coercion doesn't seem to be working as expected on 2D (and possibly N-dimensional) arrays. See:
Given:
point = ['23', 42]
coordinates = [['23', 42], ['26', 43]]
coordinates_floats = [[23.0, 42.0], [26.0, 43.0]]
Coercion doesn't normally work when trying to create a schema for coordinates:
coordinates_schema = Dry::Schema.Params do
required(:coordinates).value(:array, min_size?: 2).each do
value(:array, size?: 2).each { value(Dry::Types["coercible.float"]) }
end
end
coordinates_schema.call(coordinates: coordinates)
=> #<Dry::Schema::Result{:coordinates=>[["23", 42], ["26", 43]]} errors={:coordinates=>{0=>{0=>["must be a float"], 1=>["must be a float"]}, 1=>{0=>["must be a float"], 1=>["must be a float"]}}} path=[]>
It also didn't immediately work when I tried to exract the inner array into its own type:
point_type = Dry::Types["array"].constrained(size: 2).of(Dry::Types["coercible.float"])
point_schema = Dry::Schema.Params do
required(:point).value(point_type)
end
coordinates_schema = Dry::Schema.Params do
required(:coordinates).array(min_size?: 2) do
value(point_type)
end
end
point_schema.call(point: point)
#<Dry::Schema::Result{:point=>[23.0, 42.0]} errors={} path=[]>
coordinates_schema.call(coordinates: coordinates)
#<Dry::Schema::Result{:coordinates=>[["23", 42], ["26", 43]]} errors={:coordinates=>{0=>{0=>["must be a float"], 1=>["must be a float"]}, 1=>{0=>["must be a float"], 1=>["must be a float"]}}} path=[]>
coordinates_schema.call(coordinates: coordinates_floats)
#<Dry::Schema::Result{:coordinates=>[[23.0, 42.0], [26.0, 43.0]]} errors={} path=[]>
What eventually worked though was avoiding to expand the array definition (by using a custom type):
point_type = Dry::Types["array"].constrained(size: 2).of(Dry::Types["coercible.float"])
coordinates_schema = Dry::Schema.Params do
required(:coordinates).array(point_type, min_size?: 2)
end
coordinates_schema.call(coordinates: coordinates)
#<Dry::Schema::Result{:coordinates=>[[23.0, 42.0], [26.0, 43.0]]} errors={} path=[]>
...and since I was already on that boat, I just converted everything to a custom tye and it worked alright:
coordinates_type = Dry::Types["array"].constrained(min_size: 2).of(
Dry::Types["array"].constrained(size: 2).of(Dry::Types["coercible.float"])
)
coordinates_schema = Dry::Schema.Params do
required(:coordinates).filled(coordinates_type)
end
coordinates_schema.call(coordinates: coordinates)
#<Dry::Schema::Result{:coordinates=>[[23.0, 42.0], [26.0, 43.0]]} errors={} path=[]>
Hi everyone. Is this feature going to be released? @solnic
This feature isn't built yet, but we'd welcome it and I'd be happy to support anyone who wants to give it a go :)
Otherwise, we'll get to it eventually, but cannot make any promises regarding timing.
As an example