$: << File.dirname(__FILE__)
require "connect"

require "rubygems"
require_gem "activerecord"


#START:base
class ActiveRecord::Base
  def self.encrypt(*attr_names)
    encrypter = Encrypter.new(attr_names)
    
    before_save encrypter
    after_save  encrypter
    after_find  encrypter

    define_method(:after_find) { }
  end
end
#END:base

#START:encrypter  
class Encrypter

  # On nous passe une liste d'attributs qui devraient
  # être stockés de façon encryptée dans la bdd
  def initialize(attrs_to_manage)
    @attrs_to_manage = attrs_to_manage
  end

  # Avant de sauvegarder ou de mettre à jour, encrypter les 
  # champs avec la méthode du décalage approuvée par la
  # DGSE 
  def before_save(model)
    @attrs_to_manage.each do |field|
      model[field].tr!("a-z", "b-za")
    end
  end

  # Après la sauvegarde, les décrypter à nouveau
  def after_save(model)
    @attrs_to_manage.each do |field|
      model[field].tr!("b-za", "a-z")
    end
  end

  # Faire la même chose après avoir trouvé un enregistrement existant
  alias_method :after_find, :after_save
end
#END:encrypter

#START:order
class Order < ActiveRecord::Base
  encrypt(:name, :email)
end
#END:order

#START:driver
o = Order.new
o.name = "Dave Thomas"
o.address = "123 The Street"
o.email   = "dave@pragprog.com"
o.save
puts o.name

o = Order.find(o.id)
puts o.name
#END:driver
