I am hoping to validate the integrity of the data structure below, where the event_key
entry is necessary only for event_kind
of conference
data = {"event_info"=>
{"event_kind"=>"conference", # when 'conference', the event_key is required.
"event_id"=>"1234567",
"event_key"=>"123456789012345678901234567890AB" # required for "conference" type events
}}
The validation contains a rule on the optional event_key
which rule does not run in the absence of the optional key:
class EventSettingsContract < Dry::Validation::Contract
params do
optional(:event_info).hash do
required(:event_kind).value(included_in?: ['webinar', 'conference'])
required(:event_id).value(:string, format?: /\A[0-9]{7}\z/)
optional(:event_key).value(:string, format?: /\A[A-Z0-9]{32}\z/)
end
end
# this doesn't run when event_key is missing
rule(event_info: [:event_key, :event_id]) do
key.failure 'event_key must be present for conferences' if values[:event_kind] == 'conference' && values[:event_key].nil?
end
end
When run with the event_key
definition commented out from the data hash:
result = EventSettingsContract.new.call data
=> #<Dry::Validation::Result{:event_info=>{:event_kind=>"conference",
:event_id=>"1234567"}} errors={}>
When run with the event_key
included:
=> #<Dry::Validation::Result{:event_info=>{:event_kind=>"conference",
:event_id=>"1234567", :event_key=>"123456789012345678901234567890AB"}} errors={}>
All of this is as per documentation. Seems like it is impossible, by design, to run a rule on an optional parameter and check for its presence or absence?
How can I validate the presence of the optional event_key
parameter when and only when event_kind
is conference
?