Paranoia

repository·core·Indexed 25 days ago

https://github.com/rubysherpas/paranoia

A Rails gem providing soft-deletion functionality for ActiveRecord models. It intercepts destroy calls to set a deleted_at timestamp instead of removing rows, allowing for data recovery via the restore method. Features include custom column configuration, specialized query methods like with_deleted and only_deleted, permanent deletion via really_destroy!, and a validator to ensure associations are not soft-destroyed.

Tokens
1.5K
Snippets
3
Records
14
Agent score
34%

What's inside paranoia

  1. Configure Paranoia for ActiveRecord models

    core

    To enable soft-deletion, first add a deleted_at datetime column with an index to your table via a migration. Then, call acts_as_paranoid in your model.

    Migration Example:

    class AddDeletedAtToClients < ActiveRecord::Migration
      def change
        add_column :clients, :deleted_at, :datetime
        add_index :clients, :deleted_at
      end
    end

    Model Example:

    class Client < ActiveRecord::Base
      acts_as_paranoid
    end
  2. Install Paranoia

    core

    Install the appropriate version of Paranoia based on your Rails version in your Gemfile:

    • Rails 3: Use version ~> 1.0.
    • Rails 4 and 5: Use version ~> 2.2 (version 2.2 or greater is required for Rails 5).

    You can also install directly from GitHub branches (rails3, rails4, or rails5).

    After adding to your Gemfile, run bundle install.

  3. Configure acts_as_paranoid options

    core

    You can customize the behavior of acts_as_paranoid using the following options:

    • column: :column_name: Use a custom column instead of deleted_at (e.g., acts_as_paranoid column: :destroyed_at).
    • without_default_scope: true: Skip adding the default scope that hides deleted records.
    • after_restore_commit: true: Trigger an after_commit callback when a record is restored.
    • delete_all_enabled: true: Enables the delete_all method (disabled by default).
  4. Validate that associations are not soft-destroyed

    core

    By default, Paranoia allows a soft-destroyed object to be associated with another object. To prevent this, use the provided Rails validator:

    validates :some_association, association_not_soft_destroyed: true

    This ensures that if the associated object is soft-destroyed, the parent object becomes invalid and an error is added.

  5. Query soft-deleted records

    core

    Use these methods to control which records are returned in queries:

    • with_deleted: Includes both active and soft-deleted records.
    • only_deleted: Returns only the records that have been soft-deleted.
    • without_deleted: Excludes deleted records (useful if without_default_scope: true was used).
    • deleted? or paranoia_destroyed?: Checks if a specific instance is soft-deleted.
  6. Restore soft-deleted records

    core

    Use the restore method to bring records back from a soft-deleted state.

    • restore: Restores a single record or a collection of IDs.
    • recursive: true: Restores the record and its dependently destroyed associated records.
    • recovery_window: duration: When used with recursive: true, only restores associated records that were deleted within the specified time window of the parent record.
  7. Use Paranoia callbacks

    core

    Paranoia provides callbacks that can be used with before, after, or around hooks. These are useful for tasks like updating search engine indexes.

    Available callbacks:

    • destroy: Triggered when a record is soft-deleted.
    • real_destroy: Triggered when a record is permanently removed from the database.
    • restore: Triggered when a record is restored.
    class Product < ActiveRecord::Base
      acts_as_paranoid
    
      after_destroy      :update_document_in_search_engine
      after_restore      :update_document_in_search_engine
      after_real_destroy :remove_document_from_search_engine
    end
  8. Use soft-delete and permanent-delete methods

    core

    Once acts_as_paranoid is configured:

    • destroy: Soft-deletes the record by setting the deleted_at column to the current timestamp. The record remains in the database but is hidden from default scopes.
    • really_destroy!: Permanently removes the record from the database.
      • WARNING: This will also permanently destroy all dependent: :destroy associated records.
      • Use really_destroy!(update_destroy_attributes: false) to skip updating timestamps during the destruction process.
  9. Optimize indexes for Paranoia

    core

    Because Paranoia relies on a deleted_at column, you should update your database indexes to include a partial clause for better performance. This ensures the index only covers active (non-deleted) records.

    Example: Instead of: add_index :clients, :group_id

    Use: add_index :clients, :group_id, where: "deleted_at IS NULL"

    # Partial index for active records
    add_index :clients, :group_id, where: "deleted_at IS NULL"
    add_index :clients, [:group_id, :other_id], where: "deleted_at IS NULL"