如何从Paper Trail的版本中编辑信息?

时间:2018-05-22 16:51:39

标签: ruby paper-trail-gem redaction

对于欧盟的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]]

更新:实际上,我还需要通过关联来记录记录,所以我的例子还不够。

1 个答案:

答案 0 :(得分:0)

  

对于欧盟的GDPR合规性(用户隐私),我们需要从我们的记录版本中编辑个人身份信息。我想出了一些似乎有用的东西,但我想问一下这是否有既定的方法。

不,截至今天,2018-05-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