How to use one field to validate another


#1

I have a contract that accepts (among other, unimportant things) an :email and an :organisation_id.

I want to be able to assert that the email is unique when scoped to that organisation_id, but I’m not sure how to go about it.

If this should be modelled as a predicate, how can I reference more than one field?

If instead it should be a rule, I don’t seem to be able to write arbitrary ruby within the rule block. Is this correct?

How should I implement this requirement?


#2

This is a typical use-case for a high-level rule:

require 'dry-validation'

UserSchema = Dry::Validation.Schema do
  configure do
    def unique?(org_id, email)
      puts "email unique?: #{email} within #{org_id}"
      true
    end
  end

  required(:email).filled
  required(:org_id).filled(:int?)

  rule(unique_email: [:email, :org_id]) do |email, org_id|
    email.unique?(org_id)
  end
end

I’m planning to unify this syntax with normal rules, unfortunately it’s still using the older DSL where predicates in the DSL are called on “values” like email.unique?(org_id), in 1.0.0 it’s gonna be unique?(email, org_id). I figured I should mention that :slight_smile: