module ActiveRecord module Acts #:nodoc: module Contactable #:nodoc: class InvalidField < StandardError end class Validator def self.validate!(value, field_type) true #incluir Bazar::Validator o integrar validaciones de ActiveRecord::Base end end # Representa a un destinatario de email con @name, @email y @errors # parseado de strings tipo "Ismael Celis , Tomas Pollak " # usado en ContactForm#recipients y Shop#recipients class ParsedRecipient attr_accessor :name, :email, :errors def initialize( name='', email='' ) @name = name @email = email @errors = {} validate! end def [](att) send(att) if respond_to?(att) nil end def validate! @errors[:name] = "No puede estar vac’o" unless @name.match(/(.+)/) @errors[:email] = "Debe ser un email v‡lido" unless @email.match(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i) end def valid? @errors.empty? end def error_on(att) return @errors[att.to_sym] || nil end end def self.included(base) base.extend(ClassMethods) end module ClassMethods def acts_as_contactable(options = {}) write_inheritable_attribute(:acts_as_contactable_options, { :contactable_type => ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s, :preset => [] }.merge( options )) class_inheritable_reader :acts_as_contactable_options has_many :contactees, :as => :contactable, :dependent => :destroy has_many(:contact_fields, :through => :contactees) do def mandatory @mandatory_fields ||= find(:all,:conditions=>["contact_fields.mandatory = ?",true]) end def not_mandatory @not_mandatory_fields ||= find(:all,:conditions=>["contact_fields.mandatory = ?",false]) end def required @required_fields ||= find(:all,:conditions=>["contact_fields.required = ?",true]) end def optional @required_fields ||= find(:all,:conditions=>["contact_fields.required = ?",false]) end end before_validation :validate_parsed_recipients after_create :create_preset_fields include ActiveRecord::Acts::Contactable::InstanceMethods end end module InstanceMethods def contact_field_list=(arr) arr = [arr] unless arr.is_a?(Array) self.class.transaction do contact_fields.destroy_all #destroy_not_mandatory_fields contact_fields.reload arr.each do |c| contact_fields << ContactField.create( c ) end end true end alias_method :contact_fields=, :contact_field_list= def parsed_recipients return [] if recipients.blank? @parsed_recipients ||= recipients.split(',').collect do |line| line = line.split('<') rec_name = line[0].strip rec_email = line[1].gsub('>','') ActiveRecord::Acts::Contactable::ParsedRecipient.new(rec_name, rec_email) end end def parsed_recipients=(hash) str = [] @parsed_recipients = [] hash = [hash] unless hash.is_a?(Array) hash.each do |line| p = ActiveRecord::Acts::Contactable::ParsedRecipient.new(line[:name], line[:email]) @parsed_recipients << p str << "#{ p.name } <#{ p.email }>" if p.valid? end write_attribute('recipients',str.join(',')) end alias_method :recipients=, :parsed_recipients= def destroy_not_mandatory_fields contact_fields.destroy_all(["contact_fields.mandatory = ?",false]) end protected def validate_parsed_recipients parsed_recipients.each do |rec| self.errors.add('Destinatarios','tiene campos inv‡lidos') unless rec.valid? end end def create_preset_fields return false if self.class.acts_as_contactable_options[:preset].empty? self.contact_fields = self.class.acts_as_contactable_options[:preset].collect do |c| c.merge :mandatory=>true end end end end end end