【问题标题】:How to initialize PaperTrail versions to perform bulk insert using ActiveRecord-import gem?如何使用 ActiveRecord-import gem 初始化 PaperTrail 版本以执行批量插入?
【发布时间】:2017-08-08 07:59:00
【问题描述】:

我正在使用activerecord-import gem 在单个查询中导入多个 ActiveRecord 文档。然后我使用保存的文档 ID 初始化相关关联并导入它们,等等。

但是,对于所有保存的文档,我需要有带有 create 事件的 PaperTrail gem 版本。

是否有一些直接的方法来初始化它们以使执行批量插入成为可能?

注意:AR-Import gem 会忽略所有回调,所以我在导入后手动处理它们。

谢谢!


UPD-20/05/17:

目前我已经用PaperTrail::Model 的补丁解决了这个问题。这是我的.../initializers/paper_trail.rb

module PaperTrail
  class Version < ActiveRecord::Base
    ...    
  end

  module ModelPatch
    extend ActiveSupport::Concern

    included do
      # new method added to PaperTrail::Model module to make possible initialize
      # `create` versions right after importing resources.
      # This method contains modified code from private PaperTrail::Model::InstanceMethods#record_create
      # Difference:
      #  - instead of `create!` we use `new` but with validation and raise exception if it's invalid.
      # This is for reinsurance that if something changes after update PaperTrail gem in future
      # everything still works or need to fix it.
      def initialize_record_create_version
        return nil unless paper_trail_switched_on?
        data = {
          event:     paper_trail_event || 'create',
          whodunnit: PaperTrail.whodunnit
        }

        if changed_notably? && self.class.paper_trail_version_class.column_names.include?('object_changes')
          data[:object_changes] = if self.class.paper_trail_version_class.object_changes_col_is_json?
            changes_for_paper_trail
          else
            PaperTrail.serializer.dump(changes_for_paper_trail)
          end
        end
        new_v = send(self.class.versions_association_name).new merge_metadata(data)
        new_v.valid? ? new_v : fail("Invalid PaperTrail Version: #{new_v.errors&.messages}")
      end
    end
  end
end

PaperTrail::Model.send(:include, PaperTrail::ModelPatch)

UPD-28/01/21:

使用 PaperTrail v10.x.x 可以这样工作:

  def initialize_record_create_version
    return nil unless paper_trail.enabled?

    event = Events::Create.new(self, false)
    data = event.data.merge!(paper_trail.data_for_create)
    new_v = send(self.class.versions_association_name).new data
    new_v.valid? ? new_v : fail("Invalid PaperTrail Version: #{new_v.errors&.messages}")
  end

【问题讨论】:

  • 我尝试使用此补丁,但它不起作用,您能帮忙吗?
  • @MohdAnas 与旧 PaperTrail 版本一起使用。更新了版本 10.x.x 的解决方案。尚未使用最新的 11.x.x 进行测试。

标签: ruby-on-rails bulkinsert paper-trail-gem activerecord-import


【解决方案1】:

是的,应该可以将记录批量插入到您的versions 表中。

insert into versions
(item_id, item_type, event, created_at)
(1, "User", "create", "2016-02-29"),
(2, "User", "create", "2016-02-29"),
(1, "Widget", "create", "2016-02-29")

因为可以使用纯 SQL,所以也可以使用 ActiveRecord。请记住,PaperTrail::Version 是一个常规的 AR 模型。

【讨论】:

  • 我知道这一点。我需要找出不同的东西——如何从纸迹中初始化刚刚初始化的 AR 对象的版本。这是一个问题,因为他们只使用 :after_create 回调,当我初始化和执行批量插入时,它被忽略且无用。不过,我找到了一个使用补丁的临时解决方案。
  • 我刚刚更新了我的问题,并在补丁中包含了我当前的解决方案。
猜你喜欢
  • 2019-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多