更新:不幸的是,此方法在 Rails 2 中不起作用。自定义序列化程序可能已在 Rails 3 中添加。
原答案如下:
我认为您可以尝试使用this blog post 中所述的自定义serializer。这个特性即使在 Rails 2 中也应该存在(否则我猜这些 SO questions 不会存在)。
将属性编码为 Base64 的示例序列化程序:
# app/models/model.rb
class Model < ActiveRecord::Base
serialize :my_attr, MyEncodingSerializer
end
# lib/my_encoding_serializer.rb
class MyEncodingSerializer
require "base64"
def self.load(value)
# called when loading the value from DB
value.present? ? Base64.decode64(value) : nil
end
def self.dump(value)
# called when storing the value into DB
value.present? ? Base64.encode64(value) : nil
end
end
在 Rails 控制台中测试:
>> Model.create(my_attr: "my secret text")
D, [2016-03-14T07:17:26.493598 #14757] DEBUG -- : (0.1ms) BEGIN
D, [2016-03-14T07:17:26.494676 #14757] DEBUG -- : SQL (0.6ms) INSERT INTO `models` (`my_attr`) VALUES ('bXkgc2VjcmV0IHRleHQ=\n')
D, [2016-03-14T07:17:26.499356 #14757] DEBUG -- : (4.4ms) COMMIT
=> #<Model id: 4, my_attr: "my secret text">
您可以看到my_attr 值在保存到数据库之前自动编码。
从数据库加载当然也是透明的:
>> Model.last
D, [2016-03-14T07:19:01.414567 #14757] DEBUG -- : Model Load (0.2ms) SELECT `models`.* FROM `models` ORDER BY `models`.`id` DESC LIMIT 1
=> #<Model id: 4, my_attr: "my secret text">
所有查找器助手也应该工作,例如:
>> Model.find_by_my_attr("other text")
D, [2016-03-14T07:20:06.125670 #14757] DEBUG -- : Model Load (0.3ms) SELECT `models`.* FROM `models` WHERE `models`.`my_attr` = 'b3RoZXIgdGV4dA==\n' LIMIT 1
=> nil # nothing found here for wrong my_attr value
>> Model.find_by_my_attr("my secret text")
D, [2016-03-14T07:21:04.601898 #14757] DEBUG -- : Model Load (0.6ms) SELECT `models`.* FROM `models` WHERE `models`.`my_attr` = 'bXkgc2VjcmV0IHRleHQ=\n' LIMIT 1
=> #<Model id: 4, my_attr: "my secret text"> # FOUND!