mirror of
https://github.com/paper-trail-gem/paper_trail.git
synced 2022-11-09 11:33:19 -05:00
Navigate to an item's previous and next version.
This commit is contained in:
parent
cc794c1002
commit
b43400e33b
3 changed files with 81 additions and 4 deletions
13
README.md
13
README.md
|
@ -142,7 +142,18 @@ In fact you could use PaperTrail to implement an undo system, though I haven't h
|
|||
|
||||
## Navigating Versions
|
||||
|
||||
Once you have a particular `version` of an item you can navigate to the previous and next versions.
|
||||
You can call `previous_version` and `next_version` on an item to get it as it was/became. Note that these methods reify the item for you.
|
||||
|
||||
>> widget = Widget.find 42
|
||||
>> widget.versions.length # 4 for example
|
||||
>> widget = widget.previous_version # => widget == widget.versions.last.reify
|
||||
>> widget = widget.previous_version # => widget == widget.versions[-2].reify
|
||||
>> widget.next_version # => widget == widget.versions.last.reify
|
||||
>> widget.next_version # nil
|
||||
|
||||
As an aside, I'm undecided about whether `widget.versions.last.next_version` should return `nil` or `self` (i.e. `widget`). Let me know if you have a view.
|
||||
|
||||
If instead you have a particular `version` of an item you can navigate to the previous and next versions.
|
||||
|
||||
>> widget = Widget.find 42
|
||||
>> version = widget.versions[-2] # assuming widget has several versions
|
||||
|
|
|
@ -65,7 +65,7 @@ module PaperTrail
|
|||
def record_update
|
||||
if switched_on? && changed_and_we_care?
|
||||
versions.build merge_metadata(:event => 'update',
|
||||
:object => object_to_string(previous_version),
|
||||
:object => object_to_string(item_before_change),
|
||||
:whodunnit => PaperTrail.whodunnit)
|
||||
end
|
||||
end
|
||||
|
@ -73,7 +73,7 @@ module PaperTrail
|
|||
def record_destroy
|
||||
if switched_on?
|
||||
versions.create merge_metadata(:event => 'destroy',
|
||||
:object => object_to_string(previous_version),
|
||||
:object => object_to_string(item_before_change),
|
||||
:whodunnit => PaperTrail.whodunnit)
|
||||
end
|
||||
end
|
||||
|
@ -90,6 +90,20 @@ module PaperTrail
|
|||
version.reify if version
|
||||
end
|
||||
|
||||
# Returns the object (not a Version) as it was most recently.
|
||||
def previous_version
|
||||
last_version = version ? version.previous : versions.last
|
||||
last_version.reify if last_version
|
||||
end
|
||||
|
||||
# Returns the object (not a Version) as it became next.
|
||||
def next_version
|
||||
# NOTE: if self (the item) was not reified from a version, i.e. it is the
|
||||
# "live" item, we return nil. Perhaps we should return self instead?
|
||||
subsequent_version = version ? version.next : nil
|
||||
subsequent_version.reify if subsequent_version
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def merge_metadata(data)
|
||||
|
@ -101,7 +115,7 @@ module PaperTrail
|
|||
data.merge(PaperTrail.controller_info || {})
|
||||
end
|
||||
|
||||
def previous_version
|
||||
def item_before_change
|
||||
previous = self.clone
|
||||
previous.id = id
|
||||
changes.each do |attr, ary|
|
||||
|
|
|
@ -512,6 +512,58 @@ class HasPaperTrailModelTest < Test::Unit::TestCase
|
|||
assert_equal @version, @widget.version
|
||||
end
|
||||
|
||||
should 'return its previous self' do
|
||||
assert_equal @widget.versions[-2].reify, @widget.previous_version
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
context 'A non-reified item' do
|
||||
setup { @widget = Widget.new }
|
||||
|
||||
should 'not have a previous version' do
|
||||
assert_nil @widget.previous_version
|
||||
end
|
||||
|
||||
should 'not have a next version' do
|
||||
assert_nil @widget.next_version
|
||||
end
|
||||
|
||||
context 'with versions' do
|
||||
setup do
|
||||
@widget.save
|
||||
%w( Tom Dick Jane ).each { |name| @widget.update_attributes :name => name }
|
||||
end
|
||||
|
||||
should 'have a previous version' do
|
||||
assert_equal @widget.versions.last.reify, @widget.previous_version
|
||||
end
|
||||
|
||||
should 'have a next version' do
|
||||
assert_nil @widget.next_version
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'A reified item' do
|
||||
setup do
|
||||
widget = Widget.create :name => 'Bob'
|
||||
%w( Tom Dick Jane ).each { |name| widget.update_attributes :name => name }
|
||||
@versions = widget.versions
|
||||
@second_widget = @versions[1].reify # first widget is null
|
||||
@last_widget = @versions.last.reify
|
||||
end
|
||||
|
||||
should 'have a previous version' do
|
||||
assert_nil @second_widget.previous_version
|
||||
assert_equal @versions[-2].reify, @last_widget.previous_version
|
||||
end
|
||||
|
||||
should 'have a next version' do
|
||||
assert_equal @versions[2].reify, @second_widget.next_version
|
||||
assert_nil @last_widget.next_version
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue