Sorta resurrecting Is it possible to use dry-validation to validate ruby objects?
We use validations in a lot of our Command objects, to make sure the kwarg params passed in to #call
are what we expect. This is great for validating exactly those args, to act as a “preflight check” and prevent the command from running if the validation fails.
However, what we’re running into more and more often, it we want to not just validate that the object was passed in, but also validate things about the object. Oftentimes, one of the kwargs is a Model object, with attributes that we’d like to validate. For example, we have an Integration model, that has a settings
attribute that maps to a jsonb column on Postgres. If we have a command that can only run if some setting is set to true
, then we currently have to do something like this:
class CommandContract < Dry::Validation::Contract
params do
required(:integration).filled(type?: Integration)
end
rule(:integration) do
key.failure("my_setting is not enabled") unless value.settings["my_setting"]
end
end
It would “feel” very nice, if instead the validation or schema could match on attributes on the model object, not just values in a hash. Then the above validation might look something like this:
class CommandContract < Dry::Validation::Contract
params do
required(:integration).filled(type?: Integration) do
required(:settings).hash do
required(:my_setting).value(eql?: true)
end
end
end
end
This would also allow the validation to target the error at the right place/attribute, rather than at some higher level. (“integration settings my_setting must be true” vs “integration my_setting is not enabled”).
I know from that other thread 4 years ago, there’s no plans to support this, but I thought maybe this use-case was different enough to warrant another look. Since we have Dry::Schema.JSON
and Dry::Schema.Params
, perhaps a Dry::Schema.Attributes
or Dry::Schema.Model
?