4

我正在使用paper_trail gem来对我的模型进行版本控制。PaperTrail:控制器上下文外的info_for_paper_trail

到目前为止,我的模型依赖于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和传递prochas_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,和加上我不喜欢这个解决方案如何闻起来......

回答

4

如果您在控制器之外操作,您需要在代码中设置这些值:

::PaperTrail.controller_info = { revision_id: revision.id, revision_source_id: revision_source.id } 
::PaperTrail.whodunnit = user.id 

该模型将选择额外的值,就像它通常从控制器中获取一样。

我从查看PaperTrail::Controller模块获得此信息。特别是,请查看与以前的过滤器一样运行的set_paper_trail_controller_infoset_paper_trail_whodunnit方法。

0

我认为你可以这样做:

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