class ActiveRecord::Encryption::EncryptedAttributeType

for that attribute.
model classes. Whenever you declare an attribute as encrypted, it configures an EncryptedAttributeType
This is the central piece that connects the encryption system with encrypts declarations in the
An ActiveModel::Type::Value that encrypts/decrypts strings of text.

def build_previous_types_for(schemes)

def build_previous_types_for(schemes)
  schemes.collect do |scheme|
    EncryptedAttributeType.new(scheme: scheme, previous_type: true)
  end
end

def changed_in_place?(raw_old_value, new_value)

def changed_in_place?(raw_old_value, new_value)
  old_value = raw_old_value.nil? ? nil : deserialize(raw_old_value)
  old_value != new_value
end

def clean_text_scheme

def clean_text_scheme
  @clean_text_scheme ||= ActiveRecord::Encryption::Scheme.new(downcase: downcase?, encryptor: ActiveRecord::Encryption::NullEncryptor.new)
end

def decrypt(value)

def decrypt(value)
  with_context do
    encryptor.decrypt(value, **decryption_options) unless value.nil?
  end
rescue ActiveRecord::Encryption::Errors::Base => error
  if previous_types_without_clean_text.blank?
    handle_deserialize_error(error, value)
  else
    try_to_deserialize_with_previous_encrypted_types(value)
  end
end

def decryption_options

def decryption_options
  @decryption_options ||= { key_provider: key_provider }.compact
end

def deserialize(value)

def deserialize(value)
  cast_type.deserialize decrypt(value)
end

def encrypt(value)

def encrypt(value)
  with_context do
    encryptor.encrypt(value, **encryption_options)
  end
end

def encryption_options

def encryption_options
  @encryption_options ||= { key_provider: key_provider, cipher_options: { deterministic: deterministic? } }.compact
end

def encryptor

def encryptor
  ActiveRecord::Encryption.encryptor
end

def handle_deserialize_error(error, value)

def handle_deserialize_error(error, value)
  if error.is_a?(Errors::Decryption) && support_unencrypted_data?
    value
  else
    raise error
  end
end

def initialize(scheme:, cast_type: ActiveModel::Type::String.new, previous_type: false)

(after decrypting). ActiveModel::Type::String by default.
* :cast_type - A type that will be used to serialize (before encrypting) and deserialize
* :scheme - A +Scheme+ with the encryption properties for this attribute.

=== Options
def initialize(scheme:, cast_type: ActiveModel::Type::String.new, previous_type: false)
  super()
  @scheme = scheme
  @cast_type = cast_type
  @previous_type = previous_type
end

def previous_schemes_including_clean_text

def previous_schemes_including_clean_text
  previous_schemes.including((clean_text_scheme if support_unencrypted_data?)).compact
end

def previous_type?

def previous_type?
  @previous_type
end

def previous_types # :nodoc:

:nodoc:
def previous_types # :nodoc:
  @previous_types ||= {} # Memoizing on support_unencrypted_data so that we can tweak it during tests
  @previous_types[support_unencrypted_data?] ||= build_previous_types_for(previous_schemes_including_clean_text)
end

def previous_types_without_clean_text

def previous_types_without_clean_text
  @previous_types_without_clean_text ||= build_previous_types_for(previous_schemes)
end

def serialize(value)

def serialize(value)
  if serialize_with_oldest?
    serialize_with_oldest(value)
  else
    serialize_with_current(value)
  end
end

def serialize_with_current(value)

def serialize_with_current(value)
  casted_value = cast_type.serialize(value)
  casted_value = casted_value&.downcase if downcase?
  encrypt(casted_value.to_s) unless casted_value.nil?
end

def serialize_with_oldest(value)

def serialize_with_oldest(value)
  previous_types.first.serialize(value)
end

def serialize_with_oldest?

def serialize_with_oldest?
  @serialize_with_oldest ||= fixed? && previous_types_without_clean_text.present?
end

def support_unencrypted_data?

def support_unencrypted_data?
  ActiveRecord::Encryption.config.support_unencrypted_data && !previous_type?
end

def try_to_deserialize_with_previous_encrypted_types(value)

def try_to_deserialize_with_previous_encrypted_types(value)
  previous_types.each.with_index do |type, index|
    break type.deserialize(value)
  rescue ActiveRecord::Encryption::Errors::Base => error
    handle_deserialize_error(error, value) if index == previous_types.length - 1
  end
end