Hi,
I was wondering if adding validations to the ActiveModel or ActiveRecord instances would be possible? Composing the extra validations at the object level instead of adding more code to a model definition.
I know about contexts
and can see how a Decorator could validate a record before an event like saving but that becomes a 2-step validation.
It would work like context
but injected into an object instead of being defined in the class. Something like this:
class AgeValidator < ActiveModel::Validator
def validate(record)
record.errors.add :age, :blank unless record.age
end
end
class Person < ActiveRecord::Base
attr_accessor :name, :age
validates :name, presence: true
end
person1 = Person.new
person1.validates_with AgeValidator
person1.save
puts person1.errors.full_messages
# => ["Age can't be blank", "Name can't be blank"]
person2 = Person.new
person2.save
puts person2.errors.full_messages
# => ["Name can't be blank"]
I saw that ActiveModel::Validations#validates_with is already defined. It can be another name I thought this one was a good one. The code example isn’t the current behaviour as #save
clears errors and rerun validation defined in the class only.
I tried to mess with _validators on the object but the parent class gets updated as well instead of being contained to the object. I’m not sure if my understanding is correct on validation callbacks but it looks like these are shared between classes and their instances. If this is true is it for performance reasons?
Would it be possible that each instance gets its own validators/callbacks, duplicated from the class instead of using the one from the class?
Or maybe have another level of validators/callbacks that get populated on an object and run after the class validation callbacks are run.
Is that something possible or considered a feature request?