On pourrait penser qu'il suffit d'inclure le module de validation dans notre classe, comme ceci :

class Contact
  include ActiveRecord::Validations
  attr_accessor :name, :email, :message
 
  validates_presence_of :email, :message
end

mais ce n'est pas le cas, les validations dépendent de plusieurs méthodes d'instance de votre classe et vous serez donc obligé de les définir si vous voulez avoir accès aux validations dans votre modèle.

class Contact
  include ActiveRecord::Validations
  attr_accessor :name, :email, :message
 
  def initialize(attrs = {})
    attrs.each do |key, value|
      update_attribute(key, value)
    end
    @new_record = true
  end
 
  def save
    # Ici votre logique de sauvegarde
    # Dans notre cas, un envoi d'email ...
 
    @new_record = false
    return true # Si notre mail a pu être envoyé
  end
 
  alias :save! :save
 
  def update_attribute(key, value)
    send "#{key}=", value
  end
 
  def new_record?()
    @new_record
  end
 
  # Et enfin nos validations
  validates_presence_of :email, :message
end

Nous pouvons maintenant créer un objet Contact :

contact = Contact.new(:name => "Nico", :email => "nico@test.com")
# => #<Contact:0x132d3a0 @new_record=true, @name="Nico", @email="nico@test.com">
 
contact.valid?
# => false

Nos validations fonctionnent, notre objet n'est pas valide.

contact = Contact.new(:name => "Nico", :email => "nico@test.com", :message => "Hey !")
# => #<Contact:0x134d3c3 @new_record=true, @name="Nico", @email="nico@test.com", @message="Hey !">
 
contact.valid?
# => true

L'objet est maintenant valide.

Vous avez bien évidemment accès à toutes les méthodes mises à disposition par le module de validation, vous êtes donc en mesure de parcourir les erreurs pour savoir ce qui est à l'origine d'un objet non-valide.

Il serait très simple, à partir de ce code, de créer une classe de base dont hériteraient vos modèles non-ActiveRecord qui ont besoin des validations. Il est également très facile d'en extraire un plugin pour encore faciliter la mise en place de cette architecture.