Skip to content

Instantly share code, notes, and snippets.

@rposborne
Last active November 12, 2015 19:08
Show Gist options
  • Save rposborne/70cc6a7d02d28107fd9e to your computer and use it in GitHub Desktop.
Save rposborne/70cc6a7d02d28107fd9e to your computer and use it in GitHub Desktop.
Rollback Papertail with Block
# This utterly destroys your data, and does not attempt to put things back.
# BE WARNED
def roll_back_by_day(klass, start_at, end_at, &block)
# Turn off papertrail, we don't want our playback creating new versions.
klass.constantize.paper_trail_off!
# Play back on changes per day, at the last record on a day take snapshot
# using the block that was passed.
(end_at.to_date..start_at.to_date).reverse_each do |date|
query = PaperTrail::Version
.where(item_type: klass)
.where('created_at >= ? AND created_at <= ?', date.beginning_of_day, date.end_of_day)
.order('created_at DESC')
query.each do |version|
# Rewalk DB
item = version.reify
# Check for ID. Some papertrail versions are marked as update but don't
# have an ID
item.save!(validate: false) if item && item.id?
version.item.delete if !item && version.item
end
block.call(date) if block
puts "Total #{klass}: #{klass.constantize.count} for #{date}"
end
klass.constantize.paper_trail_on!
puts 'Done'
end
# Real use case
start_at = PaperTrail::Version.last.created_at
end_at = PaperTrail::Version.first.created_at
klass = 'Order'
ActiveRecord::Base.connection.execute("TRUNCATE summary_order_statuses RESTART IDENTITY")
roll_back_by_day(klass, start_at, end_at) do |date|
Order.distinct.pluck(:status).each do |status|
order_sql = Order.where(status: status)
Summary::OrderStatus.create(
date: date,
order_status: status,
count: order_sql.count,
dollar_amount_in_cents: order_sql.sum(:cached_total) * 100)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment