Module: DraftPunk::Model::ActiveRecordClassMethods

Defined in:
lib/activerecord_class_methods.rb

Instance Method Summary collapse

Instance Method Details

#disable_approval!Object

This will generally be only used in testing scenarios, in cases when requires_approval need to be called multiple times. Only the usage for that use case is supported. Use at your own risk for other use cases.



67
68
69
70
71
72
73
# File 'lib/activerecord_class_methods.rb', line 67

def disable_approval!
  send(:remove_const, :DRAFT_PUNK_IS_SETUP) if const_defined? :DRAFT_PUNK_IS_SETUP
  send(:remove_const, :DRAFT_NULLIFY_ATTRIBUTES) if const_defined? :DRAFT_NULLIFY_ATTRIBUTES
  fresh_amoeba do
    disable
  end
end

#draft_target_associationsArray

List of association names this model is configured to have drafts for

Returns:

  • (Array)


77
78
79
80
81
82
83
# File 'lib/activerecord_class_methods.rb', line 77

def draft_target_associations
  targets = if const_defined?(:CREATES_NESTED_DRAFTS_FOR) && const_get(:CREATES_NESTED_DRAFTS_FOR).is_a?(Array)
    const_get(:CREATES_NESTED_DRAFTS_FOR).compact
  else
    default_draft_target_associations
  end.map(&:to_sym)
end

#requires_approval(associations: [], nullify: [], set_default_scope: false) ⇒ Object

Call this method in your model to setup approval. It will recursively apply to its associations, thus does not need to be explicity called on its associated models (and will error if you try).

This model must have an approved_version_id column (Integer), which will be used to track its draft

For instance, your Business model:

class Business << ActiveRecord::Base
  has_many :employees
  has_many :images
  has_one  :address
  has_many :vending_machines

  requires_approval # When creating a business's draft, :employees, :vending_machines, :images, and :address will all have drafts created
end

Optionally, specify which associations which the user will edit - associations which should have a draft created by defining a CREATES_NESTED_DRAFTS_FOR constant for this model.

CREATES_NESTED_DRAFTS_FOR = [:address] # When creating a business's draft, only :address will have drafts created

To disable drafts for all assocations for this model, simply pass an empty array: by defining a CREATES_NESTED_DRAFTS_FOR constant for this model.

CREATES_NESTED_DRAFTS_FOR = [] # When creating a business's draft, no associations will have drafts created

WARNING: If you are setting associations via accepts_nested_attributes all changes to the draft, including associations, get set on the draft object (as expected). If your form includes associated objects which weren’t defined in requires_approval, your save will fail since the draft object doesn’t HAVE those associations to update! In this case, you should probably add that association to the associations param here.

If you want your draft associations to track their live version, add an :approved_version_id column to each association’s table. You’ll be able to access that associated object’s live version, just like you can with the original model which called requires_approval.

Parameters:

  • nullify (Array) (defaults to: [])

    A list of attributes on this model to set to null on the draft when it is created. For instance, the id and created_at columns are nullified by default, since you don’t want Rails to try to persist those on the draft.

  • set_default_scope (Boolean) (defaults to: false)

    If true, set a default scope on this model for the approved scope; only approved objects will be returned in ActiveRecord queries, unless you call Model.unscoped

  • associations (Array) (defaults to: [])

    Use internally; set associations to create drafts for in the CREATES_NESTED_DRAFTS_FOR constant

Returns:

  • true

Raises:



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/activerecord_class_methods.rb', line 47

def requires_approval(associations: [], nullify: [], set_default_scope: false)
  return unless draft_punk_table_exists?(table_name) # Short circuits if you're migrating

  associations = draft_target_associations if associations.empty?
  set_valid_associations(associations)

  raise DraftPunk::ConfigurationError, "Cannot call requires_approval multiple times for #{name}" if const_defined? :DRAFT_PUNK_IS_SETUP
  self.const_set :DRAFT_NULLIFY_ATTRIBUTES, [nullify].flatten

  amoeba do
    nullify nullify
    # Note that the amoeba associations and customize options are being set in setup_associations_and_scopes_for
  end
  setup_amoeba_for self, set_default_scope: set_default_scope
  true
end

#set_approved_version_id_callbackObject



140
141
142
143
144
145
# File 'lib/activerecord_class_methods.rb', line 140

def set_approved_version_id_callback
  lambda do |live_obj, draft_obj|
    draft_obj.approved_version_id = live_obj.id if draft_obj.respond_to?(:approved_version_id)
    draft_obj.temporary_approved_object = live_obj
  end
end

#tracks_approved_version?Boolean

Whether this model is configured to track the approved version of a draft object. This will be true if the model has an approved_version_id column

Returns:

  • (Boolean)


89
90
91
# File 'lib/activerecord_class_methods.rb', line 89

def tracks_approved_version?
  column_names.include? 'approved_version_id'
end