Class: DraftApprove::Persistor Private

Inherits:
Object
  • Object
show all
Defined in:
lib/draft_approve/persistor.rb

Overview

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

Logic for writing a Draft to the database, and for applying changes contained within a single Draft and saving them to the database.

Class Method Summary collapse

Class Method Details

.write_draft_from_model(action_type, model, options = nil) ⇒ Draft, false

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.

Write a Draft object to the database to persist any changes to the given model.

Parameters:

  • action_type (String)

    the type of action this draft will represent - CREATE, UPDATE, or DELETE

  • model (Object)

    the acts_as_draftable ActiveRecord model whose changes will be saved to the database

  • options (Hash) (defaults to: nil)

    the options to use when saving this draft, see DraftApprove::Draftable::InstanceMethods#draft_save! and DraftApprove::Draftable::InstanceMethods#draft_destroy! for details of valid options

Returns:

  • (Draft, false)

    the Draft record which was created, or false if there were no changes (ie. the result would have been a ‘no-op’ change)

Raises:

  • (ArgumentError)

See Also:



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/draft_approve/persistor.rb', line 43

def self.write_draft_from_model(action_type, model, options = nil)
  raise(ArgumentError, 'model argument must be present') unless model.present?

  if validate_model?(options) && model.invalid?
    raise(ActiveRecord::RecordInvalid, model)
  end

  DraftApprove::Transaction.ensure_in_draft_transaction do
    # Now we're in a Transaction, ensure we don't get multiple drafts for the same object
    if model.persisted? && Draft.pending_approval.where(draftable: model).count > 0
      raise(DraftApprove::Errors::ExistingDraftError, "#{model} has existing draft")
    end

    case action_type
    when Draft::CREATE
      raise(DraftApprove::Errors::AlreadyPersistedModelError, "#{model} is already persisted") if model.persisted?
      draftable_type = model.class.name
      draftable_id = nil
    when Draft::UPDATE
      raise(DraftApprove::Errors::UnpersistedModelError, "#{model} isn't persisted") unless model.persisted?
      draftable_type = model.class.name
      draftable_id = model.id
    when Draft::DELETE
      raise(DraftApprove::Errors::UnpersistedModelError, "#{model} isn't persisted") unless model.persisted?
      draftable_type = model.class.name
      draftable_id = model.id
    else
      raise(ArgumentError, "Unknown draft_action_type #{action_type}")
    end

    draft_transaction = DraftApprove::Transaction.current_draft_transaction!
    draft_options = sanitize_options_for_db(options)
    serializer = serializer_class(draft_transaction)
    changes = serializer.changes_for_model(model)

    # Don't write no-op updates!
    return false if changes.empty? && action_type == Draft::UPDATE

    return model.draft_pending_approval = Draft.create!(
      draft_transaction: draft_transaction,
      draftable_type: draftable_type,
      draftable_id: draftable_id,
      draft_action_type: action_type,
      draft_changes: changes,
      draft_options: draft_options
    )
  end
end

.write_model_from_draft(draft) ⇒ Object

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.

Write the changes represented by the given Draft object to the database.

Depending upon the type of Draft, this method may create a new record in the database, update an existing record, or delete a record.

Parameters:

  • draft (Draft)

    the Draft object whose changes should be applied and persisted to the database

Returns:

  • (Object)

    the acts_as_draftable ActiveRecord model which has been created, updated, or deleted



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/draft_approve/persistor.rb', line 102

def self.write_model_from_draft(draft)
  serializer = serializer_class(draft.draft_transaction)
  new_values_hash = serializer.new_values_for_draft(draft)
  options = draft.draft_options || {}

  case draft.draft_action_type
  when Draft::CREATE
    raise(DraftApprove::Errors::NoDraftableError, "No draftable_type for #{draft}") if draft.draftable_type.blank?

    create_method = (options.include?(CREATE_METHOD) ? options[CREATE_METHOD] : DEFAULT_CREATE_METHOD)

    model_class = Object.const_get(draft.draftable_type)
    model = model_class.send(create_method, new_values_hash)

    # We've only just persisted the model, the draft can't have referenced it before!
    draft.update!(draftable: model)

    return model
  when Draft::UPDATE
    raise(DraftApprove::Errors::NoDraftableError, "No draftable for #{draft}") if draft.draftable.blank?

    update_method = (options.include?(UPDATE_METHOD) ? options[UPDATE_METHOD] : DEFAULT_UPDATE_METHOD)

    model = draft.draftable
    model.send(update_method, new_values_hash)
    return model
  when Draft::DELETE
    raise(DraftApprove::Errors::NoDraftableError, "No draftable for #{draft}") if draft.draftable.blank?

    delete_method = (options.include?(DELETE_METHOD) ? options[DELETE_METHOD] : DEFAULT_DELETE_METHOD)

    model = draft.draftable
    model.send(delete_method)
    return model
  else
    raise(ArgumentError, "Unknown draft_action_type #{draft.draft_action_type}")
  end
end