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.