2017-12-10 23:05:11 -05:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2013-03-21 16:48:14 -04:00
|
|
|
module PaperTrail
|
2016-04-09 01:08:34 -04:00
|
|
|
# Utilities for deleting version records.
|
2013-03-21 16:48:14 -04:00
|
|
|
module Cleaner
|
2015-08-03 16:45:42 -04:00
|
|
|
# Destroys all but the most recent version(s) for items on a given date
|
|
|
|
# (or on all dates). Useful for deleting drafts.
|
2013-07-31 13:46:25 -04:00
|
|
|
#
|
|
|
|
# Options:
|
2015-08-03 16:45:42 -04:00
|
|
|
#
|
|
|
|
# - :keeping - An `integer` indicating the number of versions to be kept for
|
2016-01-16 21:48:48 -05:00
|
|
|
# each item per date. Defaults to `1`. The most recent matching versions
|
|
|
|
# are kept.
|
2015-08-03 16:45:42 -04:00
|
|
|
# - :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`.
|
|
|
|
#
|
2013-07-31 13:46:25 -04:00
|
|
|
def clean_versions!(options = {})
|
2016-03-05 17:11:08 -05:00
|
|
|
options = { keeping: 1, date: :all }.merge(options)
|
2016-02-15 20:09:59 -05:00
|
|
|
gather_versions(options[:item_id], options[:date]).each do |_item_id, item_versions|
|
|
|
|
group_versions_by_date(item_versions).each do |_date, date_versions|
|
2015-08-03 16:45:42 -04:00
|
|
|
# Remove the number of versions we wish to keep from the collection
|
|
|
|
# of versions prior to destruction.
|
2016-02-15 20:09:59 -05:00
|
|
|
date_versions.pop(options[:keeping])
|
|
|
|
date_versions.map(&:destroy)
|
2013-03-21 16:48:14 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-07-30 17:58:44 -04:00
|
|
|
private
|
2013-07-16 20:53:18 -04:00
|
|
|
|
2015-08-03 16:45:42 -04:00
|
|
|
# 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
|
2016-01-16 21:48:48 -05:00
|
|
|
# that were created on specified date. Versions are returned in
|
|
|
|
# chronological order.
|
2013-07-31 13:46:25 -04:00
|
|
|
def gather_versions(item_id = nil, date = :all)
|
2015-11-27 23:37:29 -05:00
|
|
|
unless date == :all || date.respond_to?(:to_date)
|
2016-03-05 17:19:01 -05:00
|
|
|
raise ArgumentError, "Expected date to be a Timestamp or :all"
|
2015-11-27 23:37:29 -05:00
|
|
|
end
|
2016-02-15 22:32:40 -05:00
|
|
|
versions = item_id ? PaperTrail::Version.where(item_id: item_id) : PaperTrail::Version
|
2016-01-20 00:48:29 -05:00
|
|
|
versions = versions.order(PaperTrail::Version.timestamp_sort_order)
|
2013-07-31 20:37:04 -04:00
|
|
|
versions = versions.between(date.to_date, date.to_date + 1.day) unless date == :all
|
2015-08-03 16:45:42 -04:00
|
|
|
|
|
|
|
# If `versions` has not been converted to an ActiveRecord::Relation yet,
|
|
|
|
# do so now.
|
|
|
|
versions = PaperTrail::Version.all if versions == PaperTrail::Version
|
2013-07-30 17:58:44 -04:00
|
|
|
versions.group_by(&:item_id)
|
2013-03-21 16:48:14 -04:00
|
|
|
end
|
2015-11-27 23:36:42 -05:00
|
|
|
|
|
|
|
# Given an array of versions, returns a hash mapping dates to arrays of
|
|
|
|
# versions.
|
|
|
|
# @api private
|
|
|
|
def group_versions_by_date(versions)
|
2016-09-04 00:33:29 -04:00
|
|
|
versions.group_by { |v| v.created_at.to_date }
|
2015-11-27 23:36:42 -05:00
|
|
|
end
|
2013-03-21 16:48:14 -04:00
|
|
|
end
|
|
|
|
end
|