如何编辑 Paper Trail 版本中的信息?
How to redact information from Paper Trail's versions?
为了遵守欧盟的 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]]
更新:实际上,我还需要通过关联来确定记录的范围,所以我的示例还不够。
For the EU's GDPR compliance (user privacy), we need to redact personally identifiable information form the versions of our records. I've come up with something that seems to work, but figure I should ask if there's an established way to do this.
否,截至今天,2018-05-30,没有用于 GDPR 修订的内置功能或记录的解决方案。
PaperTrail 提供了很多遍历和查询 versions
table 中的记录的方法。 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
)
为了遵守欧盟的 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]]
更新:实际上,我还需要通过关联来确定记录的范围,所以我的示例还不够。
For the EU's GDPR compliance (user privacy), we need to redact personally identifiable information form the versions of our records. I've come up with something that seems to work, but figure I should ask if there's an established way to do this.
否,截至今天,2018-05-30,没有用于 GDPR 修订的内置功能或记录的解决方案。
PaperTrail 提供了很多遍历和查询 versions
table 中的记录的方法。 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
)