Soft Delete with Paranoia
What does "Soft Delete" mean? Soft deleting an item from a database means that the row or entity is marked as deleted but not physically removed from the database. Instead it is hidden from normal users of the system but may be accessible by database or system administrators. Soft Delete ...
What does "Soft Delete" mean?
Soft deleting an item from a database means that the row or entity is marked as deleted but not physically removed from the database. Instead it is hidden from normal users of the system but may be accessible by database or system administrators.
Soft Delete in Ruby on Rails
In Ruby on Rails, there are many gems for Soft Delete. Today, I will introduce of of the most popular one is called Paranoia.
When your app is using Paranoia, calling destroy on an ActiveRecord object doesn't actually destroy the database record, but just hides it. Paranoia does this by setting a deleted_at field to the current time when you destroy a record, and hides it by scoping all queries on your model to only include records which do not have a deleted_at field.
Installation
`gem "paranoia", "~> 2.0"`
then: bundle install
Usage
Add deleted_at field to your model migrate file.
class CreateArticles < ActiveRecord::Migration def change create_table :articles do |t| t.text :title t.text :content t.datetime :deleted_at, index: true t.timestamps null: false end end end
In your model:
class Article < ActiveRecord::Base acts_as_paranoid # ... end
Now you can start your soft delete:
Article.first.destroy
This will not delete first article from your database, but change deleted_at from nil to current timestamp.
That's it! Look, it is simple and strong. But how if you really want to hard destroy first artcle from your database?
Article.first.really_destroy!
Now first article is forever gone.
If you want to use a column other than deleted_at, you can pass it as an option:
class Article < ActiveRecord::Base acts_as_paranoid column: :destroyed_at #... end
Finding records
Article.all
This will find only the article that is not deleted. If you want to find all records (both delete and not delete)
Article.with_deleted
If you want to find only the deleted records:
Article.only_deleted
If you want to check if a record is soft-deleted:
Article.first.paranoia_destroyed? #or Article.first.deleted?
Restoring deleted record
For instance, you want to restore the first record:
Article.first.restore #or Article.restore 1
If you want to restore a many records at once:
Article.restore([id1, id2, ..., idN])
If you want to restore first record and their dependently destroyed associated records:
Article.restore(1, recursive: true) # or Article.first.restore recursive: true
Callbacks
Paranoia provides several callbacks. Below are some callbacks of Paranoia:
class Article < ActiveRecord::Base after_destroy :method1 after_restore :method2 after_real_destroy :method3 #... end
You can use these events just like regular Rails callbacks with before, after.
It is too simple, but useful. Hope that this article is useful for all Rails developers. For more details, find the references below:
Paranoia Gem: https://github.com/rubysherpas/paranoia
Go Rails: https://gorails.com/episodes/soft-delete-with-paranoia
How To Configure Ruby on Rails With Paranoia Gem: https://www.netguru.co/tips/how-to-configure-ruby-on-rails-with-paranoia-gem