如何获取模型的原始预反序列化值?
问题描述:
我有一个加密类型在我的模型如何获取模型的原始预反序列化值?
attribute :name, :encrypted
这是
class EncryptedType < ActiveRecord::Type::Text
,并实现#serialize
,#deserialize
和#changed_in_place?
。
如何在反序列化之前从数据库中获取原始值?
我想创建一个rake任务来加密数据库中的字段被加密之前存在的值。所以在加密之前,name
字段包含Bob
。在加密代码后,读取该值将产生一个错误(捕获),返回一个空字符串。我想读取原始值并将其设置为普通属性,以便对其进行加密。加密后,该字段看起来像UD8yDrrXYEJXWrZGUGCCQpIAUCjoXCyKOsplsccnkNc=
。
我想要类似user.name_raw
或user.raw_attributes[:name]
。
答
有ActiveRecord::AttributeMethods::BeforeTypeCast这
提供了一种类型转换和反序列化
之前读取属性的值并具有read_attribute_before_type_cast
和attributes_before_type_cast
。此外,
它宣布了与* _before_type_cast后缀
因此,例如所有属性的方法:
User.last.created_at_before_type_cast # => "2017-07-29 23:31:10.862924"
User.last.created_at_before_type_cast.class # => String
User.last.created_at # => Sat, 29 Jul 2017 23:31:10 UTC +00:00
User.last.created_at.class # => ActiveSupport::TimeWithZone
User.last.attributes_before_type_cast # => all attributes before type casting and such
我想这将与您的自定义加密类型工作
答
由于SimpleLime建议...
namespace :encrypt do
desc "Encrypt the unencrypted values in database"
task encrypt_old_values: :environment do
User.all.each do |user|
if user.name.blank? && ! user.name_before_type_cast.blank?
User.class_variable_get(:@@encrypted_fields).each do |att|
user.assign_attributes att => user.attributes_before_type_cast[att.to_s]
end
user.save validate: false
end
end
如何定义一个名为'unencrypted'的方法来处理'encrypted'属性?所以你可以参考这个方法而不是原来的属性。这看起来更加紧密,一旦'encrypt'名字意味着数据将被加密。 –