To implement soft delete mechanism in Ruby on Rails, paranoia is the life-saver.

Sample Usage

After destroying a record, the record is still stored in the database, but it won't be returned in most of the ActiveRecord collection methods. For example, the following method call only returns Product that has not be soft-deleted:

Product.all

There are use cases that you want to see both soft-deleted and not-soft-deleted products as well. paranoia provides the following method to achieve that:

Product.with_deleted

Gotcha

However, when you are looking for associations of a deleted record, e.g. the company of a soft-deleted product:

company = Product.with_deleted.first.company

You may expect that the product is already returned, then the associated object should also be returned, right ? the answer is no. Although product.company_id exists, calling the association method #company still returns nil.

To solve this, you need to scope the association at model level

# models/product.rb
belongs_to :company, -> { with_deleted }

now Product.with_deleted.first.company returns the company record of soft-deleted product.