Soft Delete with Paranoia
Bài đăng này đã không được cập nhật trong 3 năm
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
All rights reserved