Hi.
I have an HTML form, thus params sent to server can contain empty strings.
I would like to validate that first or second attribute have to be filled (to do not allow both be empty).
And I cannot find a clear way how to do it.
class Search < Dry::Validation::Contract
params do
optional(:name).value(:string)
optional(:email).value(:string)
end
rule(:name, :email) do
if !key?(:name) && !key?(:email)
base.failure("name or email have to be filled in")
end
end
end
The “key?” method returns true for empty strings. How to treat empty strings as nils?
No need to use a rule, Schemas can do this directly.
params do
optional(:name).filled(:string)
optional(:email).filled(:string)
end
Thanks for suggestion, but this doesn’t work for me:
Search.new.call(name: "", email: "")
=> #<Dry::Validation::Result{:name=>"", :email=>""} errors={:name=>["must be filled"], :email=>["must be filled"]}>
I want to allow empty strings in this case and treat them as nils. Here I would expect that only the custom rule would error out.
Sorry, I misunderstood your question. Two things: maybe
will coerce your strings to nil, and you want to be checking values
in your rule rather than key?
class Search < Dry::Validation::Contract
params do
optional(:name).maybe(:string)
optional(:email).maybe(:string)
end
rule :name, :email do
unless values[:name] || values[:email]
base.failure("name or email have to be filled in")
end
end
end
2 Likes
Yes. This is what I was looking for. Thank you.