class DraftTransaction

@note It is strongly recommended that you do not directly create

+DraftTransaction+ objects, and instead use the supported public interface
for doing so. See +DraftApprove::Draftable::ClassMethods+ and the README
docs for this.

ActiveRecord model for persisting data about a group of draft changes which should be approved or rejected as a single, transactional group.

Each DraftTransaction has many linked Draft objects.

When a DraftTransaction is first created, it has status of pending_approval. The changes should then be reviewed and either approved or rejected.

DraftTransaction objects also have optional attribute for storing who or what created the transaction and the group of draft changes (created_by attribute), who or what reviewed the changes (reviewed_by attribute), and the reason given for approving or rejecting the changes (review_reason attribute), and finally the stack trace of any error which occurred during the process of applying the changes (error attribute).

Arbitrary extra data can also be stored in the extra_data attribute.

Note that saving 'no-op' +DraftTransaction+s is generally avoided by this library (specifically by the DraftApprove::Transaction class).

@see Draft @see DraftApprove::Draftable::ClassMethods

Constants

APPROVAL_ERROR
APPROVED
PENDING_APPROVAL

IMPORTANT NOTE: These constants are written to the database, so cannot be updated without requiring a migration of existing draft data

REJECTED

Public Instance Methods

approve_changes!(reviewed_by: nil, review_reason: nil) click to toggle source

Approve all changes in this DraftTransaction and immediately apply them to the database.

Note that applying the changes occurs within a database transaction.

@param reviewed_by [String] the user or process which approved these changes @param review_reason [String] the reason for approving these changes

@return [Boolean] true if the changes were successfully applied

# File lib/draft_approve/models/draft_transaction.rb, line 58
def approve_changes!(reviewed_by: nil, review_reason: nil)
  begin
    ActiveRecord::Base.transaction do
      self.lock!  # Avoid multiple threads applying changes concurrently
      return false unless self.status == PENDING_APPROVAL

      drafts.order(:created_at, :id).each do |draft|
        draft.apply_changes!
      end

      self.update!(status: APPROVED, reviewed_by: reviewed_by, review_reason: review_reason)
      return true
    end
  rescue StandardError => e
    # Log the error in the database table and re-raise
    self.update!(status: APPROVAL_ERROR, error: "#{e.inspect}\n#{e.backtrace.join("\n")}")
    raise
  end
end
draft_proxy_for(object) click to toggle source

Get a DraftChangesProxy for the given object in the scope of this DraftTransaction.

@param object [Object] the Draft or acts_as_draftable object to

create a +DraftChangesProxy+ for

@return [DraftChangesProxy] a proxy to get changes drafted to the given

object and related objects, within the scope of this +DraftTransaction+

@see DraftApprove::DraftChangesProxy

# File lib/draft_approve/models/draft_transaction.rb, line 99
def draft_proxy_for(object)
  serialization_module.get_draft_changes_proxy.new(object, self)
end
reject_changes!(reviewed_by: nil, review_reason: nil) click to toggle source

Reject all changes in this DraftTransaction.

@param reviewed_by [String] the user or process which rejected these changes @param review_reason [String] the reason for rejecting these changes

@return [Boolean] true if the changes were successfully rejected

# File lib/draft_approve/models/draft_transaction.rb, line 84
def reject_changes!(reviewed_by: nil, review_reason: nil)
  self.update!(status: REJECTED, reviewed_by: reviewed_by, review_reason: review_reason)
  return true
end
serialization_module() click to toggle source

@return the module used for serialization by this DraftTransaction.

@api private

# File lib/draft_approve/models/draft_transaction.rb, line 106
def serialization_module
  Object.const_get(self.serialization)
end