问题
I am using the paper_trail gem for versioning my models.
So far, my model depends on the info_for_paper_trail
method in 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
This works great in context of the controller, but is there a way that I can replicate this sort of thing outside the context of the controller (e.g., a delayed job)?
I tried creating a virtual attribute called revision
and passing a proc
into has_paper_trail
, but it errors out with a method not found
exception:
# 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!
I assume based on this result that meta
cannot take a proc
, and plus I don't like how this solution smells anyway...
回答1:
You need to set these values in your code if you're operating outside of the controller:
::PaperTrail.controller_info = { revision_id: revision.id, revision_source_id: revision_source.id }
::PaperTrail.whodunnit = user.id
The model will then pick the extra values up just like it would normally from the controller.
I derived this info from looking at the PaperTrail::Controller module. Particularly, look at the set_paper_trail_controller_info
and set_paper_trail_whodunnit
methods that get run as before filters.
回答2:
I think you can just do:
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
来源:https://stackoverflow.com/questions/17970490/papertrail-info-for-paper-trail-outside-the-context-of-a-controller