Skip to content

Instantly share code, notes, and snippets.

@swistak
Last active August 29, 2015 13:57
Show Gist options
  • Save swistak/9526550 to your computer and use it in GitHub Desktop.
Save swistak/9526550 to your computer and use it in GitHub Desktop.
Acts as Paranoid / Paranoia implementation for rails 4
# Copy of Paranoia gem without default_scope, which cannot be removed for assotiations
# in Rails 3.0. Refactored to use ActiveSupport::Concern, as it's only one file and don't need
# separate vendor/plugin.
module Paranoia
extend ::ActiveSupport::Concern
included do
scope :deleted, ->{ where.not(deleted_at: nil) }
scope :visible, ->{ where(deleted_at: nil) }
end
# Deletes the record in the database and freezes this instance to
# reflect that no changes should be made (since they can't be
# persisted). Returns the frozen instance.
#
# The row is simply removed with an SQL +DELETE+ statement on the
# record's primary key, and no callbacks are executed.
#
# To enforce the object's +before_destroy+ and +after_destroy+
# callbacks or any <tt>:dependent</tt> association
# options, use <tt>#destroy</tt>.
def delete
self.update_attribute(:deleted_at, Time.now) if persisted? && !@destroyed
@destroyed = true
freeze
end
# Called by #destroy
def destroy_row
self.update_attribute(:deleted_at, Time.now)
end
def restore!
update_attribute :deleted_at, nil
end
def destroyed?
sync_with_transaction_state
@destroyed || self.deleted_at.present?
end
def visible?
!destroyed?
end
end
require 'test_helper'
class TestModel < ActiveRecord::Base
include Paranoia
attr_accessor :stop_destroy
before_destroy :bdestroy
def bdestroy() !stop_destroy end
end
unless TestModel.table_exists?
ActiveRecord::Migration.create_table :test_models do |t|
t.string :string
t.timestamp :deleted_at
end
end
class ParanoiaTest < ActiveSupport::TestCase
# Called before every test method runs.
def setup
@test_model = TestModel.create!(string: "test")
end
test "responds to visible?" do
assert_respond_to @test_model, :visible?
end
test "adds scopes" do
assert_respond_to TestModel, :visible
assert_respond_to TestModel, :deleted
end
test "Model was created" do
assert @test_model.persisted?
assert !@test_model.destroyed?
end
test "destroying model without callbacks" do
assert @test_model.destroy
assert @test_model.destroyed?
assert !@test_model.persisted?
assert_kind_of Time, @test_model.deleted_at
end
test "deleting model" do
assert @test_model.delete
assert @test_model.destroyed?
assert !@test_model.persisted?
assert_kind_of Time, @test_model.deleted_at
end
test "Don't destroy model" do
@test_model.stop_destroy = true
assert !@test_model.destroy
assert @test_model.persisted?
assert_nil @test_model.deleted_at
end
# Called after every test method runs.
def teardown
TestModel.delete(@test_model.id)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment