我使用paper_trail gem来对我的模型进行版本控制。
到目前为止,我的模型取决于info_for_paper_trail
中的ApplicationController
方法:
class ApplicationController < ActionController::Base
# Extra columns to store along with PaperTrail `versions`
def info_for_paper_trail
{ revision_id: @revision.id, revision_source_id: @revision_source.id }
end
end
这在控制器的上下文中工作得很好,但有没有办法可以在控制器的上下文之外复制这种东西(例如,延迟的工作)?
我尝试创建一个名为revision
的虚拟属性,并将proc
传递给has_paper_trail
,但错误输出method not found
例外:
# Attempt to solve this in the model
class Resource < ActiveRecord::Base
# Virtual attribute
attr_accessor :revision
# Attempt to use virtual attribute only if set from delayed job
has_paper_trail meta: proc { |resource| resource.revision.present? ? { revision_id: resource.revision.id, revision_source_id: revision.revision_source.id } : {} }
end
# Gist of what I'm trying to do in the delayed job
resource = Resource.new
resource.revision = Revision.new(user: user, revision_source: revision_source)
resource.save!
我假设基于此结果meta
无法取proc
,而且我不喜欢此解决方案无论如何都闻起来......
答案 0 :(得分:5)
如果您在控制器外操作,则需要在代码中设置这些值:
::PaperTrail.controller_info = { revision_id: revision.id, revision_source_id: revision_source.id }
::PaperTrail.whodunnit = user.id
然后,模型将选择额外的值,就像通常从控制器那样。
我通过查看PaperTrail::Controller
模块来获取此信息。特别是,请查看以前过滤器运行的set_paper_trail_controller_info
和set_paper_trail_whodunnit
方法。
答案 1 :(得分:1)
我认为你可以做到:
class Resource < ActiveRecord::Base
# Virtual attribute
attr_accessor :revision, :revision_source
# Attempt to use virtual attribute only if set from delayed job
has_paper_trail meta: {
revision_id: :get_revision_id,
revision_source_id: get_revision_source.id
}
def get_revision_id
resource.revision.try(:id)
end
def get_revision_source_id
resource.revision_source.try(:id)
end
end