def read_encrypted_attribute(to_attr_name, cipher_class, options)
        value = read_attribute(to_attr_name)
        
        # Make sure we set the cipher for equality comparison when reading
        # from the database. This should only be done if the value is *not*
        # blank, is *not* encrypted, and hasn't changed since it was read from
        # the database. The dirty checking is important when the encypted value
        # is written to the same attribute as the unencrypted value (i.e. you
        # don't want to encrypt when a new value has been set)
        unless value.blank? || value.encrypted? || attribute_changed?(to_attr_name)
          # Create the cipher configured for this attribute
          value.cipher = create_cipher(cipher_class, options, value)
        end
        
        value
      end
def read_encrypted_attribute(to_attr_name, cipher_class, options)
        value = read_attribute(to_attr_name)
        
        # Make sure we set the cipher for equality comparison when reading
        # from the database. This should only be done if the value is *not*
        # blank, is *not* encrypted, and hasn't changed since it was read from
        # the database. The dirty checking is important when the encypted value
        # is written to the same attribute as the unencrypted value (i.e. you
        # don't want to encrypt when a new value has been set)
        unless value.blank? || value.encrypted? || attribute_changed?(to_attr_name)
          # Create the cipher configured for this attribute
          value.cipher = create_cipher(cipher_class, options, value)
        end
        
        value
      end
Reads the given attribute from the database, adding contextual
 information about how it was encrypted so that equality comparisons
 can be used