Module: DraftPunk::Model::ActiveRecordInstanceMethods

Defined in:
lib/activerecord_instance_methods.rb

Instance Method Summary collapse

Instance Method Details

#after_create_draftObject

Evaluates after the draft is created. Override in your model to implement custom behavior.



41
42
# File 'lib/activerecord_instance_methods.rb', line 41

def after_create_draft
end

#approvable_attributesArray

Which attributes of this model are published from the draft to the approved object. Overwrite in model if you don’t want all attributes of the draft to be saved on the live object.

This is an array of attributes (including has_one association id columns) which will be saved on the object when its’ draft is approved.

For instance, if you want to omit updated_at, for whatever reason, you would define this in your model:

def approvable_attributes
  self.attributes.keys - ["created_at", "updated_at"]
end

WARNING: Don’t include “created_at” if you don’t want to modify this object’s created_at!

Returns:

  • (Array)

    names of approvable attributes



35
36
37
# File 'lib/activerecord_instance_methods.rb', line 35

def approvable_attributes
  self.attributes.keys - ["created_at"]
end

#changes_require_approval?Boolean

Determines whether to edit a draft, or the original object. This only controls the object returned by editable version, and draft publishing. If changes to not require approval, publishing of the draft is short circuited and will do nothing.

Overwrite in your model to implement logic for whether to use a draft.

Returns:

  • (Boolean)


16
17
18
# File 'lib/activerecord_instance_methods.rb', line 16

def changes_require_approval?
  true # By default, all changes require approval
end

#editable_versionObject

Get the object’s draft if changes require approval; this method creates one if it doesn’t exist yet If changes do not require approval, the original approved object is returned

Returns:

  • ActiveRecord Object



77
78
79
80
# File 'lib/activerecord_instance_methods.rb', line 77

def editable_version
  return get_approved_version unless changes_require_approval?
  is_draft? ? self : get_draft
end

#get_approved_versionActiveRecord Object

Get the approved version. Intended for use on a draft object, but works on a live/approved object too

Returns:

  • (ActiveRecord Object)


85
86
87
# File 'lib/activerecord_instance_methods.rb', line 85

def get_approved_version
  approved_version || self
end

#publish_draft!ActiveRecord Object

Updates the approved version with any changes on the draft, and all the drafts’ associated objects.

If the approved version changes_require_approval? returns false, this method exits early and does nothing to the approved version.

THE DRAFT VERSION IS DESTROYED IN THIS PROCESS. To generate a new draft, simply call editable_version again on the approved object.

Returns:

  • (ActiveRecord Object)

    updated version of the approved object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/activerecord_instance_methods.rb', line 58

def publish_draft!
  @live_version  = get_approved_version
  @draft_version = editable_version
  return unless changes_require_approval? && @draft_version.is_draft? # No-op. ie. the business is in a state that doesn't require approval.

  transaction do
    save_attribute_changes_and_belongs_to_assocations_from_draft
    update_has_many_and_has_one_associations_from_draft
    # We have to destroy the draft this since we moved all the draft's has_many associations to @live_version. If you call "editable_version" later, it'll build the draft.
    # We destroy_all in case extra drafts are in the database. Extra drafts can potentially be created due to race conditions in the application.
    self.class.unscoped.where(approved_version_id: @live_version.id).destroy_all
  end
  @live_version = self.class.find(@live_version.id)
end