Validations based on external data


Hello. I have a validation that relies on some external data. Imagine we’re validating the creation of a meeting room booking, where every user has a maximum duration they are allowed.

I want to check the provided user_id belongs to someone who exists, and then that the duration is below their configured maximum. For example:

Dry::Validation.Form do

  validate(valid_user: %[user_id]) do |user_id|

  validate(valid_duration: %[user_id duration]) do |user_id, duration|
    user = User.find(user_id)
    duration < user.max_duration

Is there a good way to avoid calling User.find twice? This is actually a call to an HTTP API, so it would be great if I could reduce this to just one call. Thanks!


Having thought about it a bit more, could I write a validate method that depends on another validate method? For example:

  validate(valid_user: %[user_id]) do |user_id|

  validate(valid_duration: %[valid_user]) do |valid_user|
    duration < valid_user.max_duration


Normally, dependencies and configuration options are passed through with, see examples here:

schema = UserSchema.with(ids: [1, 2, 3])


That makes sense, thanks: but what about when those dependencies depend on something that is based on the data being validated, such as the user_id in my example.

I’d like to be able to have the UserSchema validate that the user_id is present, and if it is, then other parts of the data need to be validated based on the result of User.find(user_id). Hopefully that makes sense.