Reverting attr_encrypted fields

attr_encrypted is a Ruby plugin that allows you to store fields encrypted in the database but access then via the normal Ruby attr_accessor methods.

I work on an application that uses attr_encrypted. Recently we needed to remove encryption from a few fields. This proves to be difficult to do in a single migration due to the fact that attr_encrypted overrides the original attr_accessor for an attribute name.

I wrote a gem to make this process simple.

Here is the attribute that I want to un-encrypt, encrypted_name on the User table.

2.3.0 :001 > User.first
  User Load (0.6ms)  SELECT  `users`.* FROM `users`  ORDER BY `users`.`id` ASC LIMIT 1
 => #<User id: 1, created_at: "2016-02-20 12:27:46", updated_at: "2016-02-20 12:27:46", encrypted_name: "MoVXQ76yxiQPgJ3mdkR81A==n">

1. First, install the gem!

gem 'encryption_migrator'

2. Remove the attr_encrypted accessor from the model. Removing this allows you to use the default attribute accessor methods for the name attribute.

class User < ActiveRecord::Base
  attr_encrypted :name, :key => 'a secret key', :attribute => 'encrypted_name' # => remove this line
end

3. Generate a migration and use the gem’s unencrypt_field method. This method expects to receive the table name, the column to be un-encrypted and the encryption key.

class UnencryptFields < ActiveRecord::Migration
  def up
    unencrypt_field :users, :name, key: 'a secret key'
  end
end

4. Run the migration.

rake db:migrate

Now you can see that the encrypted_name has been replaced with name and the value is un-encrypted.

2.3.0 :001 > User.first
  User Load (0.4ms)  SELECT  `users`.* FROM `users`  ORDER BY `users`.`id` ASC LIMIT 1
 => #<User id: 1, created_at: "2016-02-20 12:27:46", updated_at: "2016-02-20 12:27:46", name: "tom">

Feedback

You can check out the source code on github. If you find this gem useful or have any suggestions please let me know!