ayushsrivastava
Mon Jan 22 2024
While creating contracts using Dry Gem it is important to keep in mind that if a validation rule is independent of a key from schema then schema will not process those keys before executing the validation rule.
For Example
class RoomAvailabilityFormContract < Dry::Validation::Contract
params do
required(:date_from).filled(:string)
required(:date_to).filled(:string)
end
rule(:date_to) do
date_from = Date.parse(values[:date_from])
date_to = Date.parse(values[:date_to])
if date_to && date_from && date_to <= date_from
key.failure('date_to must be ahead of date_from')
end
end
end
Our expectation from above contract will be if either date_to
or date_from
is missing in the schema the rule should not be executed and error should be caught while schema processes the keys
which are date_to
and date_from
But it will only work in case of date_from
because the validation rule is dependent on the date_from
key so if we have date_to
as nil the rule will still be executed and might cause other errors like in our trying to parse nil
value which does not fulfills the purpose of this gem.
To not get into such errors we should make sure that the validation rules are dependent upon the keys
that are validated in schema
So the fix in above code will be to include date_to
rule(:date_from, :date_to) do
date_from = Date.parse(values[:date_from])
date_to = Date.parse(values[:date_to])
if date_to && date_from && date_to <= date_from
key.failure('date_to must be ahead of date_from')
end
end
now before implementing the rule the schema will first validate both the keys and throw error if the values are not abiding to the schema