代码之家  ›  专栏  ›  技术社区  ›  Joshua Cheek

如何从文件追踪的版本中编辑信息?

  •  1
  • Joshua Cheek  · 技术社区  · 6 年前

    对于欧盟的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 回复  |  直到 6 年前
        1
  •  0
  •   Jared Beck    6 年前

    对于欧盟的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 ,使用 在哪里,对象改变了 从文本列中读取yaml会产生这样的错误。从文本或从 json/b 仍然允许列。

    不管怎样,如果我成功地使您对如此复杂的SQL保持警惕,那么您应该选择一种更简单的方法,也许可以迭代该用户的所有版本记录。( user.versions.find_each )