Module: ConcernsOnRails::Models::SoftDeletable::ClassMethods
- Includes:
- Support::ColumnGuard
- Defined in:
- lib/concerns_on_rails/models/soft_deletable.rb
Overview
A real module (not class_methods do) so the batch helpers and their
private fast-path predicate aren't constrained by Metrics/BlockLength
(the Stateable/Auditable precedent). ActiveSupport::Concern auto-extends it.
Instance Method Summary collapse
-
#destroy_all ⇒ Object
Override destroy_all to soft delete.
-
#really_destroy_all ⇒ Object
Hard-delete every record matching the CURRENT relation — including soft-deleted rows (only the soft-delete column's predicates are peeled off).
-
#restore_all ⇒ Object
Restore every soft-deleted record (mirror of soft_delete_all): Integer count, RecordNotSaved + rollback on failure, single UPDATE when the fast path applies.
-
#soft_deletable_by(field = nil, touch: true, default_scope: true, prefix: nil, suffix: nil) ⇒ Object
Define soft delete field and options.
-
#soft_delete_all ⇒ Object
Soft-delete every matching record.
Methods included from Support::ColumnGuard
#column_migration_hint, #ensure_columns!, #ensure_columns_on!, #schema_reachable?
Instance Method Details
#destroy_all ⇒ Object
Override destroy_all to soft delete. Kept for backwards compatibility, but prefer the
explicit soft_delete_all — silently redefining a standard AR method is a known footgun
(and unlike AR's destroy_all this returns a count, not the records).
81 82 83 |
# File 'lib/concerns_on_rails/models/soft_deletable.rb', line 81 def destroy_all soft_delete_all end |
#really_destroy_all ⇒ Object
Hard-delete every record matching the CURRENT relation — including
soft-deleted rows (only the soft-delete column's predicates are
peeled off). Note that unscope also drops a caller's own condition
on that column, so only_deleted.really_destroy_all widens to the
whole relation — use soft_deleted.delete_all to purge trash only.
(Before 1.22 this ignored the relation entirely and hard-deleted the
complete table.)
92 93 94 |
# File 'lib/concerns_on_rails/models/soft_deletable.rb', line 92 def really_destroy_all all.unscope(where: soft_delete_field).delete_all end |
#restore_all ⇒ Object
Restore every soft-deleted record (mirror of soft_delete_all): Integer count, RecordNotSaved + rollback on failure, single UPDATE when the fast path applies.
99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/concerns_on_rails/models/soft_deletable.rb', line 99 def restore_all deleted = all.public_send(soft_delete_scope_names.fetch(:soft_deleted)) return deleted.update_all(soft_delete_field => nil) if soft_delete_batch_fast_path?(:restore) ConcernsOnRails::Support::BatchOps.run( deleted, label: "ConcernsOnRails::Models::SoftDeletable", message: "failed to restore record", &:restore! ) end |
#soft_deletable_by(field = nil, touch: true, default_scope: true, prefix: nil, suffix: nil) ⇒ Object
Define soft delete field and options. Example:
soft_deletable_by :deleted_at, touch: false
soft_deletable_by :deleted_at, default_scope: false # don't hide deleted rows from .all
48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/concerns_on_rails/models/soft_deletable.rb', line 48 def soft_deletable_by(field = nil, touch: true, default_scope: true, prefix: nil, suffix: nil) self.soft_delete_field = field || :deleted_at self.soft_delete_touch = touch self.soft_delete_default_scope = default_scope ensure_columns!("ConcernsOnRails::Models::SoftDeletable", soft_delete_field, types: :datetime) return unless prefix || suffix define_soft_delete_scopes(prefix, suffix) ConcernsOnRails::Support::Affix.retire!(self, soft_delete_captured_scopes, label: "ConcernsOnRails::Models::SoftDeletable") end |
#soft_delete_all ⇒ Object
Soft-delete every matching record. Returns the Integer count of
records transitioned (already-deleted rows are skipped and keep their
original timestamp). A record that fails raises
ActiveRecord::RecordNotSaved and rolls the whole batch back — before
1.22 the rollback happened silently and the method returned nil. With
touch: false and no overridden hooks this is a single UPDATE.
66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/concerns_on_rails/models/soft_deletable.rb', line 66 def soft_delete_all pending = all.where(soft_delete_field => nil) return pending.update_all(soft_delete_field => Time.zone.now) if soft_delete_batch_fast_path?(:soft_delete) ConcernsOnRails::Support::BatchOps.run( pending, label: "ConcernsOnRails::Models::SoftDeletable", message: "failed to soft-delete record", &:soft_delete! ) end |