Class: DraftTransaction

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
lib/draft_approve/models/draft_transaction.rb

Overview

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’ DraftTransactions is generally avoided by this library (specifically by the DraftApprove::Transaction class).

Constant Summary collapse

PENDING_APPROVAL =

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

'pending_approval'.freeze
APPROVED =
'approved'.freeze
REJECTED =
'rejected'.freeze
APPROVAL_ERROR =
'approval_error'.freeze

Instance Method Summary collapse

Instance Method Details

#approve_changes!(reviewed_by: nil, review_reason: nil) ⇒ Boolean

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

Note that applying the changes occurs within a database transaction.

Parameters:

  • (defaults to: nil)

    the user or process which approved these changes

  • (defaults to: nil)

    the reason for approving these changes

Returns:

  • true if the changes were successfully applied



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# 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) ⇒ DraftChangesProxy

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

Parameters:

  • the Draft or acts_as_draftable object to create a DraftChangesProxy for

Returns:

  • a proxy to get changes drafted to the given object and related objects, within the scope of this DraftTransaction

See Also:



99
100
101
# 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) ⇒ Boolean

Reject all changes in this DraftTransaction.

Parameters:

  • (defaults to: nil)

    the user or process which rejected these changes

  • (defaults to: nil)

    the reason for rejecting these changes

Returns:

  • true if the changes were successfully rejected



84
85
86
87
# 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_moduleObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the module used for serialization by this DraftTransaction.

Returns:

  • the module used for serialization by this DraftTransaction.

API:

  • private



106
107
108
# File 'lib/draft_approve/models/draft_transaction.rb', line 106

def serialization_module
  Object.const_get(self.serialization)
end