Skip to content

Instantly share code, notes, and snippets.

@ryenski
Last active February 20, 2019 01:29
Show Gist options
  • Save ryenski/b1fdb9b7b0c244dfef3232a396c7fd94 to your computer and use it in GitHub Desktop.
Save ryenski/b1fdb9b7b0c244dfef3232a396c7fd94 to your computer and use it in GitHub Desktop.
module Trashable
extend ActiveSupport::Concern
included do
scope :trashed, ->{ unscope(where: :trashed_at).where.not(trashed_at: nil) }
scope :without_trashed, ->{ where(trashed_at: nil) }
scope :with_trashed, ->{ unscope(where: :trashed_at) }
default_scope { without_trashed }
# TODO: scope for items older than 30 days for reaping by the rake task:
# t.plans.trashed.where('trashed_at < ?', 2.weeks.ago)
scope :queued_for_deletion, -> { trashed.where('trashed_at < ?', 30.days.ago) }
end
def trash!
update_column(:trashed_at, Time.zone.now)
broadcast(:after_trash, self)
broadcast("trash_#{broadcast_model_name_key}_successful", self)
end
def restore!
update_column(:trashed_at, nil)
broadcast(:after_restore, self)
broadcast("restore_#{broadcast_model_name_key}_successful", self)
end
def trashed?
trashed_at?
end
end
require 'test_helper'
class TrashableTest < ActiveSupport::TestCase
let(:contact){ contacts(:prospect)}
it "soft delete should not actually destroy record" do
assert_no_difference "Contact.unscoped.count" do
contact.trash!
assert contact.trashed?
end
end
it "should hard delete" do
assert_difference "Contact.count", -1 do
contact.destroy
end
end
it "should restore" do
contact.trash!
contact.reload
assert_difference "Contact.count", 1 do
contact.restore!
assert_nil contact.trashed_at
refute contact.trashed?
end
end
it "should broadcast trash message" do
assert_broadcast(:trash_contact_successful) do
contact.trash!
end
end
it "should broadcast restore message" do
assert_broadcast(:restore_contact_successful) do
contact.restore!
end
end
test "queued_for_deletion should not include items trashed within 30 days" do
assert_equal 0, Contact.queued_for_deletion.count
contact.trash!
assert_equal 0, Contact.queued_for_deletion.count
contact.update_column(:trashed_at, 31.days.ago)
assert_equal 1, Contact.queued_for_deletion.count
end
it "should destroy items queued for deletion" do
assert_no_difference "Contact.unscoped.count" do
contacts(:prospect).trash!
end
assert_includes Contact.trashed.collect(&:id), contacts(:prospect).id
assert_no_difference "Contact.unscoped.count" do
Contact.queued_for_deletion.destroy_all
end
Contact.trashed.update_all(trashed_at: 31.days.ago)
assert_equal 1, Contact.queued_for_deletion.count
assert_difference "Contact.unscoped.count", -1 do
Contact.queued_for_deletion.destroy_all
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment