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

**URL:** https://discourse.dry-rb.org/t/how-to-specify-the-key-for-the-rule-if-the-value-i-want-to-get-is-an-array-inside-of-the-array-of-hashes/1194
**Category:** dry-validation
**Created:** [February 4, 2021, 7:36am UTC](https://discourse.dry-rb.org/t/how-to-specify-the-key-for-the-rule-if-the-value-i-want-to-get-is-an-array-inside-of-the-array-of-hashes/1194 "2021-02-04T07:36:44Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![mariusz-blaszczak](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/mariusz-blaszczak/32/599_2.png) [@mariusz-blaszczak](https://discourse.dry-rb.org/u/mariusz-blaszczak)
#### Post date: [February 4, 2021, 7:36am UTC](https://discourse.dry-rb.org/t/how-to-specify-the-key-for-the-rule-if-the-value-i-want-to-get-is-an-array-inside-of-the-array-of-hashes/1194/1 "2021-02-04T07:36:44Z")

</div>

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:

```ruby
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:

```ruby
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:

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

```

Here is the recreate ruby file with the above problem: [Recreate issue with dry-validation · GitHub](https://gist.github.com/mariusz-blaszczak/8d5811ad568e4ddb1e6fd79f9ce9d0c0)

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:

```ruby
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:

```auto
rule("send_params.recipients")

```

I get:

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

```

---

<div class="post-metadata">

### Author: ![mariusz-blaszczak](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/mariusz-blaszczak/32/599_2.png) [@mariusz-blaszczak](https://discourse.dry-rb.org/u/mariusz-blaszczak)
#### Post date: [February 4, 2021, 9:08am UTC](https://discourse.dry-rb.org/t/how-to-specify-the-key-for-the-rule-if-the-value-i-want-to-get-is-an-array-inside-of-the-array-of-hashes/1194/2 "2021-02-04T09:08:44Z")

</div>

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](https://github.com/dry-rb/dry-validation/issues/603)

So I added to the rule body:

```auto
next if schema_error?("send_params.recipients")

```

```auto
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

```
