dry-validation
dry-validation copied to clipboard
Support for "validate" helper within rule blocks
Support for executing predicates using validate
method within rule
blocks will make it much easier to apply various checks with extra conditions:
params do
optional(:per_page).filled(:integer)
end
rule(:per_page) do
if key?
key.failure("must be within 0..20 range") unless validate(gt?: 0, lteq?: 20)
end
end
See the original conversation: https://github.com/dry-rb/dry-validation/issues/678
Will it be possible to call validate
inside rule block without providing an explicit key failure as shown above? Predicate macros and custom registered macros have key failures defined in them already.
smth like valid?(gt?: 0, lteq?: 20)
. I'm not sure if it should be done in a single PR
Will it be possible to call validate inside rule block without providing an explicit key failure as shown above?
@musaffa yes! I just updated the example but I think @flash-gordon has a point and we should have valid?
too and I agree it should be in a separate PR as it would be a distinct new feature too.
I monkey-patched Evaluator
to add validate
as a proof of concept:
module Dry
module Validation
class Evaluator
def validate(*args)
macros = args.each_with_object([]) do |spec, macros|
case spec
when Hash
spec.each do |k, v|
macros << [k, v.is_a?(Array) ? v : [v]]
end
else
macros << Array(spec)
end
end
macros.each do |args|
macro = macro(*args.flatten(1))
instance_exec(**macro.extract_block_options(_options.merge(macro: macro)), ¯o.block)
end
end
end
end
end
Then you can do:
rule(:age) do
validate(:filled?, gt?: 18)
end
I just took these methods from Rule
to prepare the macros and this from Evaluator
to run the macros and merged them.
I want to refactor it, write tests and docs and open a PR, but I wanted to clear this out with y'all first: I think in Rule
we just assign @macros
as it's passed (@macros = macros
) here and here and move all the macro parsing to Evaluator
. Sounds good?
I forked and created a branch if you want to take a look: https://github.com/dry-rb/dry-validation/compare/main...zavan:dry-validation:macros-within-rule
No tests yet and it breaks the existing ones relying on Contract
doubles, as contract is expected to respond to #macro
.
It would be great to have this. If you could open a PR with fixed tests that would be awesome.