mirror of
https://github.com/paper-trail-gem/paper_trail.git
synced 2022-11-09 11:33:19 -05:00
Changing the :clean_versions! method on the Cleaner module so that it accepts an options hash as an argument, and additional configurable options.
This commit is contained in:
parent
9e7ebc17d7
commit
087840932d
2 changed files with 131 additions and 50 deletions
|
@ -1,14 +1,19 @@
|
|||
module PaperTrail
|
||||
module Cleaner
|
||||
|
||||
# Deletes all versions that were created on a given date except the last `keep_int` versions.
|
||||
# `date` argument should receive either an object of type `Date` or `:all` (which will clean versions on all dates).
|
||||
def clean_versions!(keep_int = 1, date = :all)
|
||||
version_hash = gather_versions(date)
|
||||
version_hash.each do |item_id, versions|
|
||||
grouping_by_date = versions.group_by { |v| v.created_at.to_date } # now group the versions by date
|
||||
grouping_by_date.each do |date, versions|
|
||||
versions.pop(keep_int)
|
||||
# Destroys all but the most recent version(s) for items on a given date (or on all dates). Useful for deleting drafts.
|
||||
#
|
||||
# Options:
|
||||
# :keeping An `integer` indicating the number of versions to be kept for each item per date.
|
||||
# Defaults to `1`.
|
||||
# :date Should either be a `Date` object specifying which date to destroy versions for or `:all`,
|
||||
# which will specify that all dates should be cleaned. Defaults to `:all`.
|
||||
# :item_id The `id` for the item to be cleaned on, or `nil`, which causes all items to be cleaned.
|
||||
# Defaults to `nil`.
|
||||
def clean_versions!(options = {})
|
||||
options = {:keeping => 1, :date => :all}.merge(options)
|
||||
gather_versions(options[:item_id], options[:date]).each do |item_id, versions|
|
||||
versions.group_by { |v| v.created_at.to_date }.each do |date, versions| # now group the versions by date and iterate through those
|
||||
versions.pop(options[:keeping]) # remove the number of versions we wish to keep from the collection of versions prior to destruction
|
||||
versions.map(&:destroy)
|
||||
end
|
||||
end
|
||||
|
@ -16,12 +21,13 @@ module PaperTrail
|
|||
|
||||
private
|
||||
|
||||
# Returns a hash of versions in this format: {:item_id => PaperTrail::Version}
|
||||
def gather_versions(date)
|
||||
raise "`date` argument must receive a Timestamp or `:all`" unless date == :all || date.respond_to?(:to_time)
|
||||
versions = date == :all ? Version.all : Version.between(date, date+1.day)
|
||||
# Returns a hash of versions grouped by the `item_id` attribute formatted like this: {:item_id => PaperTrail::Version}.
|
||||
# If `item_id` or `date` is set, versions will be narrowed to those pointing at items with those ids that were created on specified date.
|
||||
def gather_versions(item_id = nil, date = :all)
|
||||
raise "`date` argument must receive a Timestamp or `:all`" unless date == :all || date.respond_to?(:to_date)
|
||||
versions = item_id ? PaperTrail::Version.where(:item_id => item_id) : PaperTrail::Version
|
||||
versions = date == :all ? versions.all : versions.between(date.to_date, date.to_date + 1.day)
|
||||
versions.group_by(&:item_id)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,27 +3,23 @@ require 'test_helper'
|
|||
class PaperTrailCleanerTest < ActiveSupport::TestCase
|
||||
|
||||
setup do
|
||||
@animal = Animal.create :name => 'Animal'
|
||||
@animal.update_attributes :name => 'Animal from the Muppets'
|
||||
@animal.update_attributes :name => 'Animal Muppet'
|
||||
|
||||
@dog = Dog.create :name => 'Snoopy'
|
||||
@dog.update_attributes :name => 'Scooby'
|
||||
@dog.update_attributes :name => 'Scooby Doo'
|
||||
|
||||
@cat = Cat.create :name => 'Garfield'
|
||||
@cat.update_attributes :name => 'Garfield (I hate Mondays)'
|
||||
@cat.update_attributes :name => 'Garfield The Cat'
|
||||
@animals = [@animal, @dog, @cat]
|
||||
@animals = [@animal = Animal.new, @dog = Dog.new, @cat = Cat.new]
|
||||
@animals.each do |animal|
|
||||
3.times { animal.update_attribute(:name, Faker::Name.name) }
|
||||
end
|
||||
end
|
||||
|
||||
test 'Baseline' do
|
||||
assert_equal 9, PaperTrail::Version.count
|
||||
@animals.each { |animal| assert_equal 3, animal.versions.size }
|
||||
end
|
||||
|
||||
context 'Cleaner' do
|
||||
context '`clean_versions!` method' do
|
||||
context '`clean_versions!` method' do
|
||||
should 'be extended by `PaperTrail` module' do
|
||||
assert_respond_to PaperTrail, :clean_versions!
|
||||
end
|
||||
|
||||
context 'No options provided' do
|
||||
should 'removes extra versions for each item' do
|
||||
PaperTrail.clean_versions!
|
||||
assert_equal 3, PaperTrail::Version.count
|
||||
|
@ -35,34 +31,113 @@ class PaperTrailCleanerTest < ActiveSupport::TestCase
|
|||
PaperTrail.clean_versions!
|
||||
assert_equal most_recent_version_names, @animals.map { |animal| animal.versions.last.reify.name }
|
||||
end
|
||||
end
|
||||
|
||||
context '`keep_int` argument' do
|
||||
should 'modifies the number of versions ommitted from destruction' do
|
||||
PaperTrail.clean_versions!(2)
|
||||
assert_equal 6, PaperTrail::Version.all.count
|
||||
@animals.each { |animal| assert_equal 2, animal.versions.size }
|
||||
context '`:keeping` option' do
|
||||
should 'modifies the number of versions ommitted from destruction' do
|
||||
PaperTrail.clean_versions!(:keeping => 2)
|
||||
assert_equal 6, PaperTrail::Version.all.count
|
||||
@animals.each { |animal| assert_equal 2, animal.versions.size }
|
||||
end
|
||||
end
|
||||
|
||||
context '`:date` option' do
|
||||
setup do
|
||||
@animal.versions.each { |ver| ver.update_attribute(:created_at, ver.created_at - 1.day) }
|
||||
@date = @animal.versions.first.created_at.to_date
|
||||
@animal.update_attribute(:name, Faker::Name.name)
|
||||
end
|
||||
|
||||
should 'restrict the versions destroyed to those that were created on the date provided' do
|
||||
assert_equal 10, PaperTrail::Version.count
|
||||
assert_equal 4, @animal.versions.size
|
||||
assert_equal 3, @animal.versions_between(@date, @date + 1.day).size
|
||||
PaperTrail.clean_versions!(:date => @date)
|
||||
assert_equal 8, PaperTrail::Version.count
|
||||
assert_equal 2, @animal.versions(true).size
|
||||
assert_equal @date, @animal.versions.first.created_at.to_date
|
||||
assert_not_same @date, @animal.versions.last.created_at.to_date
|
||||
end
|
||||
end
|
||||
|
||||
context '`:item_id` option' do
|
||||
context 'single ID received' do
|
||||
should 'restrict the versions destroyed to the versions for the Item with that ID' do
|
||||
PaperTrail.clean_versions!(:item_id => @animal.id)
|
||||
assert_equal 1, @animal.versions.size
|
||||
assert_equal 7, PaperTrail::Version.count
|
||||
end
|
||||
end
|
||||
|
||||
context '`date` argument' do
|
||||
setup do
|
||||
@animal.versions.each { |ver| ver.update_attribute(:created_at, ver.created_at - 1.day) }
|
||||
@date = @animal.versions.first.created_at.to_date
|
||||
@animal.update_attribute(:name, 'Muppet')
|
||||
end
|
||||
|
||||
should 'restrict the version destroyed to those that were created on the date provided' do
|
||||
assert_equal 10, PaperTrail::Version.count
|
||||
assert_equal 4, @animal.versions.size
|
||||
assert_equal 3, @animal.versions_between(@date, @date + 1.day).size
|
||||
PaperTrail.clean_versions!(1, @date)
|
||||
assert_equal 8, PaperTrail::Version.count
|
||||
assert_equal 2, @animal.versions(true).size
|
||||
assert_equal @date, @animal.versions.first.created_at.to_date
|
||||
assert_equal @date + 1.day, @animal.versions.last.created_at.to_date
|
||||
context "collection of ID's received" do
|
||||
should "restrict the versions destroyed to the versions for the Item with those ID's" do
|
||||
PaperTrail.clean_versions!(:item_id => [@animal.id, @dog.id])
|
||||
assert_equal 1, @animal.versions.size
|
||||
assert_equal 1, @dog.versions.size
|
||||
assert_equal 5, PaperTrail::Version.count
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
context 'options combinations' do # additional tests to cover combinations of options
|
||||
context '`:date`' do
|
||||
setup do
|
||||
[@animal, @dog].each do |animal|
|
||||
animal.versions.each { |ver| ver.update_attribute(:created_at, ver.created_at - 1.day) }
|
||||
animal.update_attribute(:name, Faker::Name.name)
|
||||
end
|
||||
@date = @animal.versions.first.created_at.to_date
|
||||
end
|
||||
|
||||
should 'Baseline' do
|
||||
assert_equal 11, PaperTrail::Version.count
|
||||
[@animal, @dog].each do |animal|
|
||||
assert_equal 4, animal.versions.size
|
||||
assert_equal 3, animal.versions.between(@date, @date+1.day).size
|
||||
end
|
||||
end
|
||||
|
||||
context 'and `:keeping`' do
|
||||
should 'restrict cleaning properly' do
|
||||
PaperTrail.clean_versions!(:date => @date, :keeping => 2)
|
||||
[@animal, @dog].each do |animal|
|
||||
animal.versions.reload # reload the association to pick up the destructions made by the `Cleaner`
|
||||
assert_equal 3, animal.versions.size
|
||||
assert_equal 2, animal.versions.between(@date, @date+1.day).size
|
||||
end
|
||||
assert_equal 9, PaperTrail::Version.count # ensure that the versions for the `@cat` instance wasn't touched
|
||||
end
|
||||
end
|
||||
|
||||
context 'and `:item_id`' do
|
||||
should 'restrict cleaning properly' do
|
||||
PaperTrail.clean_versions!(:date => @date, :item_id => @dog.id)
|
||||
@dog.versions.reload # reload the association to pick up the destructions made by the `Cleaner`
|
||||
assert_equal 2, @dog.versions.size
|
||||
assert_equal 1, @dog.versions.between(@date, @date+1.day).size
|
||||
assert_equal 9, PaperTrail::Version.count # ensure the versions for other animals besides `@animal` weren't touched
|
||||
end
|
||||
end
|
||||
|
||||
context ', `:item_id`, and `:keeping`' do
|
||||
should 'restrict cleaning properly' do
|
||||
PaperTrail.clean_versions!(:date => @date, :item_id => @dog.id, :keeping => 2)
|
||||
@dog.versions.reload # reload the association to pick up the destructions made by the `Cleaner`
|
||||
assert_equal 3, @dog.versions.size
|
||||
assert_equal 2, @dog.versions.between(@date, @date+1.day).size
|
||||
assert_equal 10, PaperTrail::Version.count # ensure the versions for other animals besides `@animal` weren't touched
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context '`:keeping` and `:item_id`' do
|
||||
should 'restrict cleaning properly' do
|
||||
PaperTrail.clean_versions!(:keeping => 2, :item_id => @animal.id)
|
||||
assert_equal 2, @animal.versions.size
|
||||
assert_equal 8, PaperTrail::Version.count # ensure the versions for other animals besides `@animal` weren't touched
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end # clean_versions! method
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue