I know that this question is very old but let me explain how I managed to solve it:
Suppose that I have a model Post
, two users: A
and B
, that A
is authorized to update posts but he needs B
approval before committing the changes, B
is the monitor who can approve updates and can update posts as well.
- I added a method to revert the record to a particular version of it so we can update it with whatever version we want:
def revert_to(version)
raise 'not version of this model' unless self == version.item
changes = version.changeset.select{ |k, v| not SKIP_FIELDS.include?(k) }.map{ |k,v| [k.to_sym, v[1]] }.to_h
self.update_attributes(changes)
end
I got that method from this Stackoverflow answer but I modified it a bit.
- The trick is to not update the record itself if the current user
A
hasn't authorized to commit changing, rather than updating, a new Paper Trail version will be created, then the monitor B
can accept the new changes by reverting the original record to that version.
For that I used a function from Paper Trail core paper_trail.record_update()
.
A:
p = Post.find(1)
p.title = "A new pending version"
p.paper_trail.record_update(nil)
B as a monitor:
p = Publication.find(1)
p.revert_to(p.versions.last)
B as an editor:
p = Publication.find(1)
p.title = "p will be updated to this version immediately"
p.paper_trail.record_update(nil)
p.save
- I added
has_paper_trail
to Post model but I restricted it on create and destroy actions because as I said above I don't want a new version to be created after updating, I want it to be created before.
has_paper_trail :on => [:create, :destroy]