How to return error for presence of certain keys

I was wondering if anyone else has found a need to validate against the presence of a key in a hash.
Right now dry-validation has a macro for required(...) and optional(...). I think it would be nice to have another macro like forbidden(...) (or some other word, like exclude or refute) that would fail validation if the key given was present in the input hash.

Here’s a use-case:
I am validating a settings hash. The hash can be updated but some keys are restricted.
If the input hash contains a restricted key I want to return an error letting the user know that they cannot modify that key.
Right now the closest I can get is optional(:key).value(:none?) but this isn’t the desired behavior because passing restricted_key: nil should also be forbidden.

I am going to implement a custom rule, but I was curious to see if there is a cleaner way to validate against the presence of a key.

This is possible with dry-validation 1.0.0 (currently available as RC2 pre-release). Here’s an example:

require 'dry/validation'

class SettingsContract < Dry::Validation::Contract
  schema do
    required(:foo).filled(:string)
    required(:bar).filled(:string)

    optional(:restricted)
  end

  rule(:restricted) do
    key.failure("key :restricted cannot be present") if values.key?(:restricted)
  end
end

sc = SettingsContract.new

puts sc.(foo: 'foo', bar: 'bar', restricted: nil).errors.to_h.inspect
# {:restricted=>["key :restricted cannot be present"]}

Does this help?

Thanks @solnic, looks like it may be time for us to upgrade all of our dry-rb libraries!

1 Like

Ahh yeah it’s a very good moment. dry-validation 1.0.0 final should be ready very soon.