Generic and specific rule for a nested array

Hi again,

This is probably an odd example, but I was wondering if it’s possible and/or how else we should be handling this. We have a deeply nested schema with an array of hashes where one of the attributes is also array of hashes. Now for that nested array it doesn’t seem to be possible to add an error both to the attribute itself and to its nested children. You can find a trivial example where an error is always being set below:

class RulesExample < ApplicationContract
  params do
    required(:outer).array(:hash) do
      required(:inner).array(:hash) do
        required(:attr).filled(:integer)
      end
    end
  end

  rule(:outer).each do
    value[:inner].each_with_index do |inner, idx|
      inner_nested_key = key(key.path.keys + [:inner, idx])
      inner_nested_key.failure("Inner #{inner} specific failure")
    end

    inner_key = key(key.path.keys + [:inner])
    inner_key.failure('Inner generic failure')
  end
end

This fails with

NoMethodError: undefined method `[]' for nil:NilClass
from /usr/local/bundle/gems/dry-validation-1.4.2/lib/dry/validation/message_set.rb:108:in `block in messages_map'

From glancing over the code it seems to me like once a message is being found on outer[i]inner[j] it can no longer be set on outer[i]inner because in the first example a hash is expected and in the other it’s an array (or the other way around).

Having just one rule (either on the attribute or on the children) works just fine.

That’s a bug, please report an issue about it in dry-validation project.

All done, thanks!

1 Like