Reusing both schema and rules

Hello,

Is there a way to reuse contracts in full (schema AND rules)?

#!/usr/bin/env ruby

require 'dry-validation'

module Contracts
  class ApplicationContract < Dry::Validation::Contract
  end

  class AddressContract < ApplicationContract
    json do
      required(:street).filled(:string)
      required(:zip_code).value(:integer)
    end

    rule(:zip_code) do
      key.failure(:invalid) unless values[:maximum].between?(10_000, 99_999)
    end
  end

  class UserContract < ApplicationContract
    params do
      required(:name).filled(:string)
      required(:address).schema(AddressContract.schema)
    end
  end
end

result = Contracts::UserContract.new.call(name: 'John', address: { street: 'Madison street' })
raise if result.errors.to_h.dig('address', 'zip_code').nil?
# Does not raise. The schema is successfully re-used.

result = Contracts::UserContract.new.call(name: 'John', address: { street: 'Madison street', zip_code: 123 })
raise unless result.errors.to_h.dig('address', 'zip_code').nil?
# Exception raised. I'd like to fix this.

I know it’s possible to use register_macro as a workaround but that’s really not what I’m looking for; my wish is to re-use a contract in full (schema+rules) without having to move rules around.

Is it something that’s supported in the current version of dry-validation?

Thanks!

1 Like

There was movement toward this a while back, but that seems to have stalled.