module AttrEncrypted::Adapters::ActiveRecord

Public Instance Methods

assign_attributes_with_attr_encrypted(*args) click to toggle source
# File lib/attr_encrypted/adapters/active_record.rb, line 35
def assign_attributes_with_attr_encrypted(*args)
  perform_attribute_assignment :assign_attributes_without_attr_encrypted, *args
end
attributes_with_attr_encrypted=(*args) click to toggle source
# File lib/attr_encrypted/adapters/active_record.rb, line 41
def attributes_with_attr_encrypted=(*args)
  perform_attribute_assignment :attributes_without_attr_encrypted=, *args
end
perform_attribute_assignment(method, new_attributes, *args) click to toggle source
# File lib/attr_encrypted/adapters/active_record.rb, line 26
def perform_attribute_assignment(method, new_attributes, *args)
  return if new_attributes.blank?

  send method, new_attributes.reject { |k, _|  self.class.encrypted_attributes.key?(k.to_sym) }, *args
  send method, new_attributes.reject { |k, _| !self.class.encrypted_attributes.key?(k.to_sym) }, *args
end
reload_with_attr_encrypted(*args, &block) click to toggle source

github.com/attr-encrypted/attr_encrypted/issues/68

# File lib/attr_encrypted/adapters/active_record.rb, line 9
def reload_with_attr_encrypted(*args, &block)
  result = reload_without_attr_encrypted(*args, &block)
  self.class.encrypted_attributes.keys.each do |attribute_name|
    instance_variable_set("@#{attribute_name}", nil)
  end
  result
end

Protected Instance Methods

attr_encrypted(*attrs) click to toggle source

attr_encrypted method

Calls superclass method
# File lib/attr_encrypted/adapters/active_record.rb, line 51
def attr_encrypted(*attrs)
  super
  options = attrs.extract_options!
  attr = attrs.pop
  options.merge! encrypted_attributes[attr]

  define_method("#{attr}_changed?") do
    send(attr) != decrypt(attr, send("#{options[:attribute]}_was"))
  end

  define_method("#{attr}_was") do
    decrypt(attr, send("#{options[:attribute]}_was")) if send("#{attr}_changed?")
  end

  alias_method "#{attr}_before_type_cast", attr
end
attribute_instance_methods_as_symbols() click to toggle source
Calls superclass method
# File lib/attr_encrypted/adapters/active_record.rb, line 68
def attribute_instance_methods_as_symbols
  # We add accessor methods of the db columns to the list of instance
  # methods returned to let ActiveRecord define the accessor methods
  # for the db columns
  
  # Use with_connection so the connection doesn't stay pinned to the thread.
  connected = ::ActiveRecord::Base.connection_pool.with_connection(&:active?) rescue false
  
  if connected && table_exists?
    columns_hash.keys.inject(super) {|instance_methods, column_name| instance_methods.concat [column_name.to_sym, :"#{column_name}="]}
  else
    super
  end
end
method_missing_with_attr_encrypted(method, *args, &block) click to toggle source

Allows you to use dynamic methods like find_by_email or scoped_by_email for encrypted attributes

NOTE: This only works when the :key option is specified as a string (see the README)

This is useful for encrypting fields like email addresses. Your user's email addresses are encrypted in the database, but you can still look up a user by email for logging in

Example

class User < ActiveRecord::Base
  attr_encrypted :email, :key => 'secret key'
end

User.find_by_email_and_password('test@example.com', 'testing')
# results in a call to
User.find_by_encrypted_email_and_password('the_encrypted_version_of_test@example.com', 'testing')
# File lib/attr_encrypted/adapters/active_record.rb, line 100
def method_missing_with_attr_encrypted(method, *args, &block)
  if match = /^(find|scoped)_(all_by|by)_([_a-zA-Z]\w*)$/.match(method.to_s)
    attribute_names = match.captures.last.split('_and_')
    attribute_names.each_with_index do |attribute, index|
      if attr_encrypted?(attribute)
        args[index] = send("encrypt_#{attribute}", args[index])
        attribute_names[index] = encrypted_attributes[attribute.to_sym][:attribute]
      end
    end
    method = "#{match.captures[0]}_#{match.captures[1]}_#{attribute_names.join('_and_')}".to_sym
  end
  method_missing_without_attr_encrypted(method, *args, &block)
end