The main intention for dry-validation is to validate data, usually coming in from the boundaries of your system (e.g. from user input or other untrusted/unknown sources), which is why it works with simple arrays and hashes as input data.
In a typical dry-rb-style app, by the time this data winds up encapsulated in rich objects, we’d expect the data to be valid.
Can you pass your objects’ attributes as a hash to your dry-validation schemas instead?
Hi, I know this thread is old but it’s still relevant to me so I think it might be a better idea to revive it than start a new one.
I have a system where the meaning of valid change with context. Typically a valid draft is not a valid published item.
I’d like to use dry validation to validate an object (my idea is an activerecord object but it could be anything ) because in this case the source is the database.
I hoped dry-validation would work with any kind of (nested) object but it seems it does not.
I do not think my case is so special so I’m reposting the same question : Is there a way to validate an object ? If not : will there be soon ? if not : what do you suggest to validate data from database ?
Hey, validating objects won’t be supported, dry-validation is for validating data exclusively, which are represented by ruby primitives (Hash, Array, String, etc).
what do you suggest to validate data from database ?
Dump them to arrays/hashes and then you can apply validation schemas, although that would not be a common use case.
It’s a little strange to serialize an object graph in order to be able to validate it.
Do you think it may be a good idea to wrap an ActiveRecord in a kind of Delegator overriding the def [](key) which would call public_send(key) on its delegate and then wrap it again in the same Kind of Delegator?
That delegator would some kind of adapter for object graphs (in my case ActiveRecord but I can imagine a graph of Poros having the same behavior) to make it look like a hash.
In other terms, what’s the part of the Hash interface that you rely on as input? How hard would it be for another object to quack like a hash?
This could do (I didn’t thoroughly test it though):
class ValidationProxy
def initialize(model)
@model = model
end
def [](attr)
@model.public_send(attr)
end
def key?(attr)
@model.attributes.key?(attr.to_s)
end
alias has_key? key?
end
class User < ActiveRecord::Base
end
Schema = Dry::Validation.Schema do
required(:name).filled(:str?)
end
valid_user = User.new(name: 'foo')
invalid_user = User.new(name: '')
puts Schema.call(ValidationProxy.new(valid_user)).success? #=> true
puts Schema.call(ValidationProxy.new(invalid_user)).errors #=> {:name=>["must be filled"]}
Actually I think we need to use respond_to? as implementation of key? and also wrap the result in a ValidationProxy if it is an ActiveRecord but those are implementations details.
My main question to @solnic was mostly about an interface for what it means to be a ValidationInput.
Of course the proxy needs key? and [] but does it need something else and how stable are those requirements ?
Would you be interested in a PR in that direction ? With tests and documentation of course