[dry-validation] oMethodError: undefined method `key?' for #<Array

Hello, community. I am using dry-validation gem v. 1.0 and I have following validator, which validate nested data structure (array of hashes, which has nested arrays/hashes and etc)

require 'dry-validation'

class Specification < Dry::Validation::Contract
    params do
        required(:specification).array(:hash?).schema do
        required(:title).filled(:str?)
        required(:id).filled(:str?)
        required(:items).array(:hash?).schema do
            required(:pos).filled(:str?)
            required(:title).filled(:str?)
            optional(:description).filled(:str?)
            optional(:extra_description).filled(:hash?).schema do
                optional(:rotation).filled(:str?)
                optional(:amount).filled(:str?)
              end
              optional(:inputs).filled(:hash?).schema do
                optional(:unit_price).filled(:bool)
                optional(:total_net).filled(:bool)        
              end
              optional(:additional_inputs).array(:hash?).schema do
                optional(:label).filled(:str?)
                optional(:placeholder).filled(:str?)
                optional(:description).filled(:str?)
              end 
            end
        end
    end
end

When I try to run Specification.call(specification: specification) where specification is:

[{:dada=>"title",
      :name=>"name",
      :id=>"123",
      :items=>[{:pos=>"1", :title=>"title"}, {:pos=>"1.1", :title=>"chapter title", :description=>"<p>some <b>html</b> stuff </p>"}]}]

I've gotNoMethodError: undefined method key?' for #<Array:0x00007fd0060d7bf8> error message. Any hints about what I am doing wrong? Thanks in advance

Okay, I solved it a different way:

JobSpecificationSchema = Dry::Schema.Params do
    required(:specification).array(:hash) do
      required(:title).filled(:string)
      required(:id).filled(:string)
      required(:items).array(:hash) do
        required(:pos).filled(:string)
        required(:title).filled(:str?)
        optional(:description).filled(:string)
        optional(:extra_description).hash(ExtraDescriptionSchema)
        optional(:inputs).hash(InputsSchema)
        optional(:additional_inputs).array(:hash, AdditionalInputs)
      end
    end
  end

  ExtraDescriptionSchema = Dry::Schema.Params do
    optional(:rotation).filled(:string)
    optional(:amount).filled(:string)
  end

  InputsSchema = Dry::Schema.Params do
    optional(:unit_price).filled(:bool)
    optional(:total_net).filled(:bool)
  end

  AdditionalInputs = Dry::Schema.Params do
    optional(:label).filled(:str?)
    optional(:placeholder).filled(:str?)
    optional(:description).filled(:str?)
  end

Works as expected

1 Like