Hey Stas. This question is tangentially similar to what was asked earlier here but I think your question can probably be solved through pattern matching in this situation. Here’s a little script you can tinker with that should demonstrate a potential solution for you:
#! /usr/bin/env ruby
# frozen_string_literal: true
# Save as `snippet`, then `chmod 755 snippet`, and run as `./snippet`.
require "bundler/inline"
gemfile true do
source "https://rubygems.org"
gem "amazing_print"
gem "debug"
gem "dry-schema"
end
module Schemas
User = Dry::Schema.Params { required(:name).filled :string }
Admin = Dry::Schema.Params { required(:email).filled :string }
Unknown = proc { "Unknown parameters." }
end
class Validator
SCHEMAS = {user: Schemas::User, admin: Schemas::Admin, unknown: Schemas::Unknown}.freeze
def initialize schemas: SCHEMAS
@schemas = schemas
end
def call(parameters) = find_schema(parameters).call parameters
private
attr_reader :schemas
def find_schema parameters
case parameters
in name:, **remainder unless remainder.key? :email then schemas.fetch :user
in email:, **remainder unless remainder.key? :name then schemas.fetch :admin
else schemas.fetch :unknown
end
end
end
validator = Validator.new
ap validator.call({name: "Jane Doe"})
ap validator.call({email: "Jill Smith"})
ap validator.call({name: "Invalid", email: "admin@example.com"})
When running the above you’ll see the following output:
#<Dry::Schema::Result{:name=>"Jane Doe"} errors={} path=[]>
#<Dry::Schema::Result{:email=>"Jill Smith"} errors={} path=[]>
"Unknown parameters."
You’ll notice that the validator handles a user, admin, and unknown data (simple use case but you can make it as sophisticated as needed). Basically, I’m using pattern matching to delegate to the appropriate schema to determine which schema to validate against. This assumes you have distinguishing keys withing your parameters to route to the appropriate schema, though.
Anyway, might be of interest as one solution.