我正在使用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,你可能不需要我的东西,只是提到了它,因为它很相似:)