Module: Finalizers::Model

Extended by:
ActiveSupport::Concern
Defined in:
app/models/finalizers/model.rb

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#deleted?Boolean

Returns:

  • (Boolean)


122
# File 'app/models/finalizers/model.rb', line 122

def deleted? ; state=='deleted' ; end

#destroy(force: false) ⇒ Object



124
125
126
127
# File 'app/models/finalizers/model.rb', line 124

def destroy(force: false)
  raise 'Called destroy() directly instead of using erase()' unless force
  super()
end

#destroy!(force: false) ⇒ Object



128
129
130
131
# File 'app/models/finalizers/model.rb', line 128

def destroy!(force: false)
  raise 'Called destroy!() directly instead of using erase!()' unless force
  destroy(force: true) || _raise_record_not_destroyed
end

#eraseObject

runs save callbacks, but not validations or validation callbacks intent is to parallel destroy()‘s behavior



135
136
137
138
139
140
# File 'app/models/finalizers/model.rb', line 135

def erase
  self.state     = 'deleted'
  self.state_at  = Time.current if respond_to?(:state_at=) && state_changed?
  self.delete_at = nil if respond_to?(:delete_at=)
  save validate: false
end

#erase!Object



141
142
143
144
145
146
# File 'app/models/finalizers/model.rb', line 141

def erase!
  self.state     = 'deleted'
  self.state_at  = Time.current if respond_to?(:state_at=) && state_changed?
  self.delete_at = nil if respond_to?(:delete_at=)
  save! validate: false
end

#finalize_and_destroy!Object

called by EraserJob may call directly for testing

Raises:



165
166
167
168
169
170
171
172
173
174
175
176
# File 'app/models/finalizers/model.rb', line 165

def finalize_and_destroy!
  # finalizers execute outside of the destroy transaction (and callback sequence).
  # this intentionally allows finalizers to do whatever action and /persist/ that finalized state
  #   so if a later finalizer aborts, the previous ones don't have to repeat themselves.
  # finalizers should still be idempotent though, as a finalizer could re-run due to an error
  #   persisting that state, server failure, etc.
  run_callbacks :finalize do
    destroy force: true
  end
  raise RetryJobError, "#{self.class.name} #{id} finalizers did not complete" unless destroyed?
  self
end

#safe_eraseObject

must define on model def erasable?

...

end



153
154
155
156
157
158
159
160
# File 'app/models/finalizers/model.rb', line 153

def safe_erase
  if erasable?
    erase
  else
    errors.add :base, "#{self.class.model_name.human} in use"
    false
  end
end