We use crypt_keeper gem having version 1.1.1. The crypt_keeper directive is defined on the Company model. The Company model has two sub-classes sharing the same companies table as follows using single-table inheritance (STI).
class Company < ActiveRecord::Base; end
class Firm < Company; end
class Client < Company; end
It failed to decrypt the companies table though as follows.
> Company.decrypt_table!
# ActiveRecord::SubclassNotFound: Invalid single-table inheritance type: Firm is not a subclass of
# from /Users/vishaltelangre/.rbenv/versions/2.4.0/lib/ruby/gems/2.4.0/gems/activerecord-5.1.4/lib/active_record/inheritance.rb:203:in `find_sti_class'
The ::decrypt_table! method works for models having no STI implemented on them.
Since, our Company model/table had STI implementation, we needed to modify the ::decrypt_method as follows to make the decryption work for us.
company_klass = Class.new(ActiveRecord::Base).tap { |c| c.table_name = Company.table_name }
# By default, `inheritance_column` is set to `type`.
# Since the sub-classes are descendants of `Company`
# and not of `company_klass` class, it fails with an error:
# "ActiveRecord::SubclassNotFound: Invalid single-table inheritance type:
# Firm is not a subclass of".
# To avoid running into this error, we needed to set the inheritance column on
# the temporary class `company_klass` to nil.
company_klass.inheritance_column = nil
company_klass.all.to_a; # establish a database connection in development mode
company_klass.find_each do |record|
Company.crypt_keeper_fields.each do |field|
record.send("#{field}=", Company.find(record.id)[field])
end
record.save!
end
We pushed above change as a migration and performed a deployment to execute that migration on our servers.
Then we pushed another change with
modified Gemfile and Gemfile.lock with gem upgrade changes,
encryptor changed from aes_new to active_support,
and another migration to execute Company.encrypt_table!.
And performed another deployment on our servers.
This approach worked for us. I am not sure if we could've done anything better though.
I can submit a PR if it looks okay.
We use
crypt_keeper
gem having version1.1.1
. Thecrypt_keeper
directive is defined on theCompany
model. TheCompany
model has two sub-classes sharing the samecompanies
table as follows using single-table inheritance (STI).Since we want to upgrade the
crypt_keeper
gem to2.x
version, we followed the steps provided at https://github.com/jmazzi/crypt_keeper#migrating-from-cryptkeeper-1x-to-20.It failed to decrypt the
companies
table though as follows.The
::decrypt_table!
method works for models having no STI implemented on them.Since, our
Company
model/table had STI implementation, we needed to modify the::decrypt_method
as follows to make the decryption work for us.We pushed above change as a migration and performed a deployment to execute that migration on our servers.
Then we pushed another change with
aes_new
toactive_support
,Company.encrypt_table!
. And performed another deployment on our servers.This approach worked for us. I am not sure if we could've done anything better though. I can submit a PR if it looks okay.
Thanks.