Module: Glib::SoftDeletable::ClassMethods

Defined in:
app/models/concerns/glib/soft_deletable.rb

Instance Method Summary collapse

Instance Method Details

#__mark_for_destruction_behaviourObject



31
32
33
# File 'app/models/concerns/glib/soft_deletable.rb', line 31

def __mark_for_destruction_behaviour
  @__glib_mark_for_destruction_behaviour ||= :disallowed
end

#__soft_deletable_associationsObject



48
49
50
# File 'app/models/concerns/glib/soft_deletable.rb', line 48

def __soft_deletable_associations
  @__glib_soft_deletable_associations ||= []
end

#__validate_soft_deletable_association!(name) ⇒ Object

Raises:

  • (ActiveRecord::ConfigurationError)


68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'app/models/concerns/glib/soft_deletable.rb', line 68

def __validate_soft_deletable_association!(name)
  reflection = reflect_on_association(name)
  unless reflection
    raise(
      ActiveRecord::ConfigurationError,
      "#{self.name} declares `soft_deletes_with #{name.inspect}` but has no association `#{name}`. " \
      'Make sure the association is declared before `soft_deletes_with`.'
    )
  end

  return if reflection.polymorphic? # Can't resolve a single target class for polymorphic associations.

  return if reflection.klass.include?(Glib::SoftDeletable)

  raise(
    ActiveRecord::ConfigurationError,
    "#{self.name} declares `soft_deletes_with #{name.inspect}`, " \
    "but #{reflection.klass.name} does not include Glib::SoftDeletable"
  )
end

#__validate_soft_delete_index!(column_name) ⇒ Object

Dev/test safety net: ensure the soft-delete column is indexed.

This must never depend on the database already existing. It runs at class-load time, which also happens during db:create, db:setup, migrations and cold CI boots — moments when the database or the table may not exist yet. In those cases we skip silently; the check runs again (and can raise) once the schema is present.



58
59
60
61
62
63
64
65
66
# File 'app/models/concerns/glib/soft_deletable.rb', line 58

def __validate_soft_delete_index!(column_name)
  return unless table_exists?
  return if connection.index_exists?(table_name, column_name)

  raise ActiveRecord::ConfigurationError, "#{table_name}.#{column_name} need to be indexed"
rescue ActiveRecord::NoDatabaseError, ActiveRecord::ConnectionNotEstablished
  # Database not available yet (e.g. during `db:create`/`db:setup` or a cold boot).
  # Defer the check rather than making model definition require a live database.
end

#auto_hide_soft_deleted_recordsObject



19
20
21
22
23
24
# File 'app/models/concerns/glib/soft_deletable.rb', line 19

def auto_hide_soft_deleted_records
  column_name = :deleted_at
  default_scope { where(column_name => nil) }

  __validate_soft_delete_index!(column_name) if Rails.env.development? || Rails.env.test?
end

#on_mark_for_destruction(behaviour) ⇒ Object

behaviour can be either :soft_destroy or `:hard_destroy``



27
28
29
# File 'app/models/concerns/glib/soft_deletable.rb', line 27

def on_mark_for_destruction(behaviour)
  @__glib_mark_for_destruction_behaviour = behaviour
end

#soft_deletes_with(*association_names) ⇒ Object

Declarative way to register associations that should be soft-deleted together with this record. Preferred over overriding soft_deletable_associations because it lets us validate at load time (in dev/test) that each association exists and its model is itself soft-deletable.

NOTE: Declare the associations (e.g. has_many) before calling this so the reflection exists.



40
41
42
43
44
45
46
# File 'app/models/concerns/glib/soft_deletable.rb', line 40

def soft_deletes_with(*association_names)
  @__glib_soft_deletable_associations = association_names.map(&:to_sym)

  if Rails.env.development? || Rails.env.test?
    @__glib_soft_deletable_associations.each { |name| __validate_soft_deletable_association!(name) }
  end
end