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?