How to specify the key for the rule if the value I want to get is an array inside of the array of hashes

Hello. I have following problem. I don’t know how to specify the key for the rule if the value I want to get is an array inside of the array of hashes.

Here is my contract:

class BulkSendContract < Dry::Validation::Contract
  params do
    required(:send_params).array(:hash) do
      required(:id).value(:integer)
      required(:recipients).array(:string)
    end
  end

  rule("send_params").each do
    recipients = value[:recipients]
    recipients.each do |recipient|
      stripped_value = recipient.gsub(/[-()\s]/, '')
      key.failure("Fax number '#{recipient}' has invalid format") unless stripped_value =~ /^\+?[0-9]{6,}$/
    end
  end
end

And the params I send:

send_params = [{ id: 1, recipients: ["2", ["2", "1"]] }]

The params are invalid. Schema expects recipients to be array of Strings, but it has nested array.
I want to make the contract not enter into the rule validating the recipients if schema for recipients is invalid.
With current implementation it enters and because the recipients are not strings, it raises error:

NoMethodError (undefined method `gsub' for ["2", "1"]:Array):

Here is the recreate ruby file with the above problem: Recreate issue with dry-validation · GitHub

I tried to code the rule differently, but I did not find a good way for it.

I would like to have something like this:

rule("send_params[].recipients").each do
  stripped_value = value.gsub(/[-()\s]/, '')
  key.failure("Fax number '#{recipient}' has invalid format") unless stripped_value =~ /^\+?[0-9]{6,}$/
end

But it does not ever enter ito the rule block - even if the schema is valid.

If I do:

rule("send_params.recipients")

I get:

BulkSendContract.rule specifies keys that are not defined by the schema: ["send_params.recipients"] (Dry::Validation::InvalidKeysError)

I found out that:

Rule path syntax doesn’t support array items yet.

source: Can't set rule for array of hashes · Issue #603 · dry-rb/dry-validation · GitHub

So I added to the rule body:

next if schema_error?("send_params.recipients")
class BulkSendContract < ApplicationContract
  params do
    required(:send_params).array(:hash) do
      required(:id).value(:integer)
      required(:recipients).array(:string)
    end
  end

  rule("send_params").each do
    next if schema_error?("send_params.recipients")

    recipients = value[:recipients]
    recipients.each do |recipient|
      stripped_value = recipient.gsub(/[-()\s]/, '')
      key.failure("Fax number '#{recipient}' has invalid format") unless stripped_value =~ /^\+?[0-9]{6,}$/
    end
  end
end