How to define a non-empty Array of non-empty Strings?

Since I couldn’t quickly find an answer on Google or in the guides, what is the correct way to define a non-empty Array of non-empty Strings? I would to reject values such as "", [], [nil], and [""].

This is what I’ve come up with, but I’m wondering if there’s a better way?

class Validation < Dry::Validation::Contract

  params do
    required(:foo).filled(:array).each(:str?).each(:filled?)
  end

end

If you are avoiding type constants, this seems like the shortest way:

required(:foo).value(array[:string].constrained(min_size: 1)).each(:filled?)

It’s so useful to have a filled-string type that I always define one sooner or later

Types = Dry.Types(default: :strict)

module Types
  FilledString = String.constrained(filled: true)
end

class Validation < Dry::Validation::Contract
  params do
    required(:foo).value(array[Types::FilledString].constrained(min_size: 1))
  end
end

Or, construct a “array of non-empty strings”-Type and require foo to be filled to get the non-empty array:

class Validation < Dry::Validation::Contract
  params do
    required(:foo).filled(Types::Array.of(Types::String.constrained(filled: true)))
  end
end

Which, as I realize now, is quite the same as @alassek wrote. Sorry for the noise. (I’m just more used to using Types everywhere)

Considering requiring a non-empty Array of non-empty Strings is probably fairly common, is there a built-in type specifically for this? Or perhaps, should there be a built-in type for this?

I think a custom rule would work better, especially since it can use custom error messages

1 Like