### Install Paranoia Gem for Rails Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Specifies the gem version to install for different Rails versions. Includes options for installing directly from GitHub. Requires running 'bundle install' afterwards. ```ruby gem "paranoia", "~> 1.0" ``` ```ruby gem "paranoia", "~> 2.2" ``` ```ruby gem "paranoia", github: "rubysherpas/paranoia", branch: "rails3" ``` ```ruby gem "paranoia", github: "rubysherpas/paranoia", branch: "rails4" ``` ```ruby gem "paranoia", github: "rubysherpas/paranoia", branch: "rails5" ``` -------------------------------- ### Paranoia Gem Callback Example for Search Engine Integration Source: https://github.com/rubysherpas/paranoia/blob/core/README.md This example illustrates how to use Paranoia's callbacks (`after_destroy`, `after_restore`, `after_real_destroy`) to integrate with a search engine. It defines methods to update search engine documents when records are marked as deleted, restored, or permanently removed. ```ruby 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 ``` -------------------------------- ### Shared Examples: Verify Paranoid Model Behavior in Ruby Source: https://github.com/rubysherpas/paranoia/wiki/Testing-with-rspec These shared examples provide a robust way to test that models are correctly implementing `acts_as_paranoid`. They check for the presence of the `deleted_at` column and index, and verify the behavior of the `deleted_at` where clause, including its exclusion when `unscoped` is used. This relies on the Shoulda Matchers gem. ```ruby shared_examples_for 'a Paranoid model' do it { is_expected.to have_db_column(:deleted_at) } it { is_expected.to have_db_index(:deleted_at) } it 'adds a deleted_at where clause' do expect(described_class.all.where_sql).to include('`deleted_at` IS NULL') end it 'skips adding the deleted_at where clause when unscoped' do expect(described_class.unscoped.where_sql.to_s).not_to include('`deleted_at`') # to_s to handle nil. end end ``` -------------------------------- ### RSpec Matcher: Test Acts As Paranoid in Ruby Source: https://github.com/rubysherpas/paranoia/wiki/Testing-with-rspec This RSpec matcher simplifies testing if a model correctly includes the `acts_as_paranoid` functionality. It requires the `rails_helper` and `RSpec` to be set up. The primary input is the model being tested. ```ruby require 'rails_helper' RSpec.describe Foo, type: :model do it { is_expected.to act_as_paranoid } end ``` -------------------------------- ### Access Soft-Deleted Associations Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Provides an example of how to override an association getter method to include soft-deleted records when accessing them, using 'unscoped'. ```ruby def product Product.unscoped { super } end ``` -------------------------------- ### Restore Records with Paranoia Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Demonstrates various ways to restore soft-deleted records using the Paranoia gem. This includes restoring single records, multiple records, recursively restoring associated records, and restoring within a specified time window. It also shows how to trigger after_commit callbacks during restoration. ```ruby Client.restore([id1, id2, ..., idN]) Client.restore(id, :recursive => true) client.restore(:recursive => true) Client.restore(id, :recursive => true, :recovery_window => 2.minutes) client.restore(:recursive => true, :recovery_window => 2.minutes) ``` ```ruby class Client < ActiveRecord::Base acts_as_paranoid after_restore_commit: true after_commit :commit_called, on: :restore # or after_restore_commit :commit_called ... end ``` -------------------------------- ### Optimizing Database Indexes for Paranoia Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Provides guidance on adapting database indexes to work efficiently with Paranoia's soft deletion. It demonstrates how to replace existing `add_index` statements with `where` clauses to only index active (not deleted_at IS NULL) records, and offers alternatives for unique indexes using computed columns or a sentinel column. ```ruby add_index :clients, :group_id, where: "deleted_at IS NULL" add_index :clients, [:group_id, :other_id], where: "deleted_at IS NULL" ``` ```ruby add_index :clients, [:group_id, 'COALESCE(deleted_at, false)'], unique: true ``` ```ruby add_column :clients, :active, :boolean add_index :clients, [:group_id, :active], unique: true class Client < ActiveRecord::Base acts_as_paranoid column: :active, sentinel_value: true def paranoia_restore_attributes { deleted_at: nil, active: true } end def paranoia_destroy_attributes { deleted_at: current_time_from_proper_timezone, active: nil } end end ``` -------------------------------- ### Restore a Soft-Deleted Record Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Demonstrates how to restore a soft-deleted record using its ID with the 'restore' class method. ```ruby Client.restore(id) ``` -------------------------------- ### Generate Migration for Deleted At Column Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Provides the Rails generator command to create a migration for adding the 'deleted_at' datetime column with an index. Also shows the Ruby code for the migration itself. ```shell bin/rails generate migration AddDeletedAtToClients deleted_at:datetime:index ``` ```ruby class AddDeletedAtToClients < ActiveRecord::Migration def change add_column :clients, :deleted_at, :datetime add_index :clients, :deleted_at end end ``` -------------------------------- ### Enable Global `delete_all` in Paranoia Gem Source: https://github.com/rubysherpas/paranoia/blob/core/README.md This snippet shows how to globally enable the `delete_all` method for the Paranoia gem by setting a configuration flag in the Rails environment file. This allows for mass deletion of soft-deleted records. ```ruby Paranoia.delete_all_enabled = true ``` -------------------------------- ### Correct acts_as_paranoid on Concrete Class (Ruby) Source: https://github.com/rubysherpas/paranoia/wiki/Inheriting-from-an-Abstract-Class Illustrates the correct way to use `acts_as_paranoid` by applying it directly to the concrete inherited class, ensuring proper table name resolution in SQL queries. ```ruby class BaseClass < ActiveRecord::Base self.abstract_class = true end class InheritedClass < BaseClass acts_as_paranoid end # This will produce the correct SQL query >> InheritedClass.scoped.where_sql # => "WHERE (`inherited_classes`.deleted_at IS NULL)" ``` -------------------------------- ### Perform Soft and Permanent Deletion Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Illustrates how to perform a soft delete by calling 'destroy' on a model instance, which sets the 'deleted_at' timestamp. Also shows how to permanently delete a record using 'really_destroy!'. ```ruby >> client.deleted_at # => nil >> client.destroy # => client >> client.deleted_at # => [current timestamp] ``` ```ruby >> client.deleted_at # => nil >> client.really_destroy! # => client ``` -------------------------------- ### Enable Paranoia Soft Deletion in Model Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Demonstrates how to enable the paranoia soft-deletion functionality in an ActiveRecord model by including the 'acts_as_paranoid' macro. ```ruby class Client < ActiveRecord::Base acts_as_paranoid # ... end ``` -------------------------------- ### Query Records Including Deleted Ones Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Demonstrates how to retrieve all records, including those that have been soft-deleted, by using the 'with_deleted' scope. ```ruby Client.with_deleted ``` -------------------------------- ### Enable `delete_all` for Specific Models in Paranoia Gem Source: https://github.com/rubysherpas/paranoia/blob/core/README.md This snippet demonstrates how to enable the `delete_all` method on a per-model basis when using the Paranoia gem. It's configured directly within the model definition using the `acts_as_paranoid` macro. ```ruby class User < ActiveRecord::Base acts_as_paranoid(delete_all_enabled: true) end ``` -------------------------------- ### Incorrect acts_as_paranoid on Abstract Base Class (Ruby) Source: https://github.com/rubysherpas/paranoia/wiki/Inheriting-from-an-Abstract-Class Demonstrates the incorrect application of `acts_as_paranoid` on an abstract base class, leading to an empty table name in SQL queries. This pattern should be avoided. ```ruby class BaseClass < ActiveRecord::Base self.abstract_class = true acts_as_paranoid end class InheritedClass < BaseClass end # This will produce an incorrect SQL query >> InheritedClass.scoped.where_sql # => "WHERE (``.deleted_at IS NULL)" ``` -------------------------------- ### Include Soft-Deleted Associated Objects Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Shows how to use a lambda with 'with_deleted' on a belongs_to association to ensure that soft-deleted associated objects are included in queries. ```ruby class Person < ActiveRecord::Base belongs_to :group, -> { with_deleted } end Person.includes(:group).all ``` -------------------------------- ### Skip Default Scope with Paranoia Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Demonstrates how to prevent Paranoia from automatically adding a default scope to queries, allowing direct access to all records regardless of their deletion status. ```ruby class Client < ActiveRecord::Base acts_as_paranoid without_default_scope: true ... end ``` -------------------------------- ### Query Only Soft-Deleted Records Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Shows how to retrieve only the records that have been soft-deleted by applying the 'only_deleted' scope. ```ruby Client.only_deleted ``` -------------------------------- ### Use Custom Deletion Column with Paranoia Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Explains how to configure Paranoia to use a custom column name for storing the deletion timestamp instead of the default 'deleted_at'. ```ruby class Client < ActiveRecord::Base acts_as_paranoid column: :destroyed_at ... end ``` -------------------------------- ### Paranoia Association Callback Behavior Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Explains how `dependent: :destroy` associations behave when the parent model uses Paranoia. If both parent and child models have `acts_as_paranoid`, `destroy` on the parent calls `destroy` on children, preserving them with `deleted_at`. If the child does not use Paranoia, `destroy` on the parent will truly destroy the children. ```ruby class Client < ActiveRecord::Base acts_as_paranoid has_many :emails, dependent: :destroy end class Email < ActiveRecord::Base acts_as_paranoid belongs_to :client end ``` ```ruby class Client < ActiveRecord::Base acts_as_paranoid has_many :emails, dependent: :destroy end class Email < ActiveRecord::Base belongs_to :client end ``` -------------------------------- ### Per-Model Sentinel Value Configuration in Paranoia Source: https://github.com/rubysherpas/paranoia/wiki/Custom-sentinel-values This Ruby code snippet demonstrates how to configure a specific sentinel value for the Paranoia gem on a per-model basis. This is useful for overriding the global default or when specific models require a different non-null value to represent a 'not deleted' state, thus avoiding potential issues with unique index constraints involving nullable columns. ```ruby acts_as_paranoid sentinel_value: DateTime.new(0) ``` -------------------------------- ### Association Validation with Paranoia Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Shows how to use the `association_not_soft_destroyed` validator provided by the Paranoia gem to prevent associations with soft-deleted records. If a soft-deleted record is associated, the main object will be marked as invalid with a validation error. ```ruby validates :some_assocation, association_not_soft_destroyed: true ``` -------------------------------- ### Query Records Excluding Deleted Ones Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Illustrates how to retrieve only records that have not been soft-deleted, useful when the default scope is disabled, using the 'without_deleted' scope. ```ruby Client.without_deleted ``` -------------------------------- ### Skip Timestamp Updates on Permanent Deletion Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Shows how to call 'really_destroy!' with the 'update_destroy_attributes: false' option to skip updating timestamps during a permanent deletion, affecting associated records as well. ```ruby >> client.really_destroy!(update_destroy_attributes: false) # => client ``` -------------------------------- ### Global Sentinel Value Configuration in Paranoia Source: https://github.com/rubysherpas/paranoia/wiki/Custom-sentinel-values This Ruby code snippet shows how to set a global sentinel value for the Paranoia gem within a Rails application. This configuration is typically placed in an initializer file and affects all models using the gem, providing a consistent non-null value to represent 'not deleted' records and mitigate unique index constraint problems. ```ruby Paranoia.default_sentinel_value = DateTime.new(0) ``` -------------------------------- ### Check if a Record is Soft-Deleted Source: https://github.com/rubysherpas/paranoia/blob/core/README.md Provides two methods, 'paranoia_destroyed?' and 'deleted?', to check if an individual record instance has been soft-deleted. ```ruby client.paranoia_destroyed? ``` ```ruby client.deleted? ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.