在提交ActiveRecord事务结束之前报告更改.(Ruby on Rails)



我正在使用ActiveRecord(Rails)在嵌套事务中进行一系列复杂的数据库交互,涉及各种model.update(...)model.where(...).first_or_create(..)

在交易结束之前,我想报告一下实际发生了什么变化,以及即将编写的内容。大概ActiveRecord保存了这些信息,但我还不知道在哪里。

我的代码类似于(半伪代码

def run options
  begin
  ActiveRecord::Base.transaction do |tranny|
    options[:files].each do |file|
      raw_data = open(file)
      complex_data_stuff raw_data, options
    end
    report
  rescue => e
    "it all went horribly wrong, here's why: #{e.message}"
  end
end
def report tranny
  changes = {}
  tranny.whatschanged?.each do |ch|
    changes[ch.model.class.name] = {} unless changes[ch.model.class.name]
    if changes[ch.model.class.name][ch.kind_of_update]
      changes[ch.model.class.name][ch.kind_of_update] += 1
    else
      changes[ch.model.class.name][ch.kind_of_update] = 1
    end
  end
  changes
end

我该如何实现这样的目标?

http://api.rubyonrails.org/classes/ActiveModel/Dirty.html

这是"脏模型"的最新版本,它跟踪当前对象和保存版本之间的差异。您可以通过"更改"方法访问更改,就像您的尝试一样。

我在我的一个项目中添加了一些额外的东西来存储上次更新中更改的内容:它存储在一个实例变量中,因此只能在内存中的特定对象中访问(即,如果从数据库中重新加载,则无法看到它)。

module ActiveRecord
  class Base
    attr_accessor :changed_in_last_save
    before_save :set_changed_in_last_save_hash
    def set_changed_in_last_save_hash
      self.changed_in_last_save_hash = self.changes
    end
    def changed_in_last_save
      self.changed_in_last_save_hash || {}
    end
  end
end

你肯定需要ActiveModel::Dirty,你可能不需要我的东西,只是提到了它,因为它很相似:)

最新更新