module Sequel::Plugins::Paranoid

Public Class Methods

configure(model, options = {}) click to toggle source
# File lib/sequel/plugins/paranoid.rb, line 6
def self.configure(model, options = {})
  model.sequel_paranoid_options = options = {
    :deleted_at_field_name      => :deleted_at,
    :deleted_by_field_name      => :deleted_by,
    :delete_method_name         => :soft_delete,
    :enable_deleted_by          => false,
    :deleted_scope_name         => :deleted,
    :non_deleted_scope_name     => :not_deleted,
    :ignore_deletion_scope_name => :with_deleted,
    :enable_default_scope       => false,
    :soft_delete_on_destroy     => false,
    :deleted_column_default     => nil,
    :include_validation_helpers => false,
  }.update(options)

  delete_attributes = proc do |*args|
    destroy_options = args.first || {}

    attrs = {}
    # set the deletion time
    attrs[options[:deleted_at_field_name]] = Time.now

    # set the deletion author
    if options[:enable_deleted_by] && destroy_options && destroy_options[:deleted_by]
      attrs[options[:deleted_by_field_name]] = destroy_options[:deleted_by]
    end

    attrs
  end

  ds_mod = Module.new do
    # scope for deleted items
    define_method(options[:deleted_scope_name]) do
      send(options[:ignore_deletion_scope_name]).exclude(Sequel.qualify(model.table_name, options[:deleted_at_field_name]) => options[:deleted_column_default])
    end

    # scope for non-deleted items
    define_method(options[:non_deleted_scope_name]) do
      filter(Sequel.qualify(model.table_name, options[:deleted_at_field_name]) => options[:deleted_column_default])
    end

    # scope for both
    define_method(options[:ignore_deletion_scope_name]) do
      unfiltered
    end

    # soft delete the records without callbacks.
    define_method(options[:delete_method_name]) do |*args|
      update(delete_attributes.call(*args))
    end

  end

  im_mod = Module.new do

    define_method(options[:delete_method_name]) do |*args|
      self.set(delete_attributes.call(*args))
      self.save
    end

  end

  model.instance_eval do
    dataset_module ds_mod
    include im_mod

    plugin SoftDeleteOnDestroy if options[:soft_delete_on_destroy]
    plugin EnableDefaultScope if options[:enable_default_scope]
    plugin Validations if options[:include_validation_helpers]
  end
end