ruby - 如何编辑来自 Paper Trail 版本的信息?
问题描述
对于欧盟的 GDPR 合规性(用户隐私),我们需要从我们的记录版本中编辑个人身份信息。我想出了一些似乎可行的方法,但我应该问一下是否有既定的方法可以做到这一点。
class User < ActiveRecord::Base
has_paper_trail
end
user = User.create! name: 'Josh'
user.update_attributes name: 'Josh2'
user.update_attributes name: 'Josh3'
user.destroy!
def self.get_data
PaperTrail::Version.order(:id).where(item_id: 1).map { |ver| [ver.event, ver.object, ver.object_changes] }
end
# ===== BEFORE =====
get_data
# => [["create", nil, {"id"=>[nil, 1], "name"=>[nil, "Josh"]}],
# ["update", {"id"=>1, "name"=>"Josh"}, {"name"=>["Josh", "Josh2"]}],
# ["update", {"id"=>1, "name"=>"Josh2"}, {"name"=>["Josh2", "Josh3"]}],
# ["destroy", {"id"=>1, "name"=>"Josh3"}, nil]]
PaperTrail::Version.where_object_changes(name: 'Josh').each do |ver|
ver.object['name'] = 'REDACTED' if ver.object && ver.object['name'] == 'Josh'
if oc = ver.object_changes
oc['name'] = oc['name'].map { |name| name == 'Josh' ? 'REDACTED' : name }
ver.object_changes = oc
end
ver.save!
end
# ===== AFTER =====
get_data
# => [["create", nil, {"id"=>[nil, 1], "name"=>[nil, "REDACTED"]}],
# ["update",
# {"id"=>1, "name"=>"REDACTED"},
# {"name"=>["REDACTED", "Josh2"]}],
# ["update", {"id"=>1, "name"=>"Josh2"}, {"name"=>["Josh2", "Josh3"]}],
# ["destroy", {"id"=>1, "name"=>"Josh3"}, nil]]
更新:实际上,我还需要通过关联来确定记录的范围,所以我的示例还不够。
解决方案
对于欧盟的 GDPR 合规性(用户隐私),我们需要从我们的记录版本中编辑个人身份信息。我想出了一些似乎可行的方法,但我应该问一下是否有既定的方法可以做到这一点。
不,截至今天,2018 年 5 月 30 日,没有用于 GDPR 修订的内置功能或文档化解决方案。
PaperTrail 提供了许多迭代和查询versions
表中记录的方法。where_object_changes
就是这样一个特性,但它会生成一些相当复杂的 SQL。
where_object_changes(name: 'Joan')
SELECT "versions".*
FROM "versions"
WHERE .. ("versions"."object_changes" LIKE '%
name:
- Joan
%' OR "versions"."object_changes" LIKE '%
name:
-%
- Joan
%')
您可能有理由担心此查询的正确性。事实上,从PT 9.0.0开始,使用where_object_changes
从文本列中读取 YAML 会引发错误。json/b
仍然允许从文本或列中读取 JSON 。
无论如何,如果我成功地让您对如此复杂的 SQL 保持警惕,那么您应该选择一种更简单的方法,也许迭代该用户的所有版本记录 ( user.versions.find_each
)