Module: Draftsman::Model::InstanceMethods

Defined in:
lib/draftsman/model.rb

Instance Method Summary collapse

Instance Method Details

#draft?Boolean

Returns whether or not this item has a draft.

Returns:

  • (Boolean)


190
191
192
# File 'lib/draftsman/model.rb', line 190

def draft?
  send(self.class.draft_association_name).present?
end

#draft_creationObject

Creates object and records a draft for the object’s creation. Returns ‘true` or `false` depending on whether or not the objects passed validation and the save was successful.



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# File 'lib/draftsman/model.rb', line 196

def draft_creation
  transaction do
    # We want to save the draft after create
    return false unless self.save

    data = {
      :item      => self,
      :event     => 'create',
      :whodunnit => Draftsman.whodunnit,
      :object    => object_attrs_for_draft_record
    }
    data[:object_changes] = changes_for_draftsman(previous_changes: true) if track_object_changes_for_draft?
    data = (data)

    send "build_#{self.class.draft_association_name}", data

    if send(self.class.draft_association_name).save
      write_attribute "#{self.class.draft_association_name}_id", send(self.class.draft_association_name).id
      self.update_column "#{self.class.draft_association_name}_id", send(self.class.draft_association_name).id
      return true
    else
      raise ActiveRecord::Rollback and return false
    end
  end
end

#draft_destroyObject

Trashes object and records a draft for a ‘destroy` event.



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/draftsman/model.rb', line 223

def draft_destroy
  transaction do
    data = {
      :item      => self,
      :event     => 'destroy',
      :whodunnit => Draftsman.whodunnit,
      :object    => object_attrs_for_draft_record
    }

    # Stash previous draft in case it needs to be reverted later
    if self.draft?
      attrs = send(self.class.draft_association_name).attributes

      data[:previous_draft] = if self.class.draft_class.previous_draft_col_is_json?
        attrs
      else
        Draftsman.serializer.dump(attrs)
      end
    end

    data = (data)

    if send(self.class.draft_association_name).present?
      send(self.class.draft_association_name).update_attributes! data
    else
      send("build_#{self.class.draft_association_name}", data)
      send(self.class.draft_association_name).save!
      send "#{self.class.draft_association_name}_id=", send(self.class.draft_association_name).id
      self.update_column "#{self.class.draft_association_name}_id", send(self.class.draft_association_name).id
    end

    trash!

    # Mock `dependent: :destroy` behavior for all trashable associations
    dependent_associations = self.class.reflect_on_all_associations(:has_one) + self.class.reflect_on_all_associations(:has_many)

    dependent_associations.each do |association|

      if association.klass.draftable? && association.options.has_key?(:dependent) && association.options[:dependent] == :destroy
        dependents = self.send(association.name)
        dependents = [dependents] if (dependents && association.macro == :has_one)

        dependents.each do |dependent|
          dependent.draft_destroy unless dependent.draft? && dependent.send(dependent.class.draft_association_name).destroy?
        end if dependents
      end
    end
  end
end

#draft_updateObject

Updates object and records a draft for an ‘update` event. If the draft is being updated to the object’s original state, the draft is destroyed. Returns ‘true` or `false` depending on if the object passed validation and the save was successful.



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
# File 'lib/draftsman/model.rb', line 276

def draft_update
  transaction do
    save_only_columns_for_draft

    # We want to save the draft before update
    return false unless self.valid?

    # If updating a creation draft, also update this item
    if self.draft? && send(self.class.draft_association_name).create?
      data = {
        :item      => self,
        :whodunnit => Draftsman.whodunnit,
        :object    => object_attrs_for_draft_record
      }

      if track_object_changes_for_draft?
        data[:object_changes] = changes_for_draftsman(changed_from: self.send(self.class.draft_association_name).changeset)
      end

      data = (data)
      send(self.class.draft_association_name).update_attributes data
      self.save
    # Destroy the draft if this record has changed back to the original record
    elsif changed_to_original_for_draft?
      send(self.class.draft_association_name).destroy
      send "#{self.class.draft_association_name}_id=", nil
      self.save
    # Save a draft if record is changed notably
    elsif changed_notably_for_draft?
      data = {
        :item      => self,
        :whodunnit => Draftsman.whodunnit,
        :object    => object_attrs_for_draft_record
      }
      data = (data)

      # If there's already a draft, update it.
      if send(self.class.draft_association_name).present?
        data[:object_changes] = changes_for_draftsman if track_object_changes_for_draft?
        send(self.class.draft_association_name).update_attributes data
        update_skipped_attributes
      # If there's not draft, create an update draft.
      else
        data[:event]          = 'update'
        data[:object_changes] = changes_for_draftsman if track_object_changes_for_draft?
        send "build_#{self.class.draft_association_name}", data
        
        if send(self.class.draft_association_name).save
          update_column "#{self.class.draft_association_name}_id", send(self.class.draft_association_name).id
          update_skipped_attributes
        else
          raise ActiveRecord::Rollback and return false
        end
      end
    # If record is a draft and not changed notably, then update the draft.
    elsif self.draft?
      data = {
        :item      => self,
        :whodunnit => Draftsman.whodunnit,
        :object    => object_attrs_for_draft_record
      }
      data[:object_changes] = changes_for_draftsman(changed_from: @object.draft.changeset) if track_object_changes_for_draft?
      data = (data)
      send(self.class.draft_association_name).update_attributes data
      update_skipped_attributes
    # Otherwise, just save the record
    else
      self.save
    end
  end
rescue Exception => e
  false
end

#object_attrs_for_draft_record(object = nil) ⇒ Object

Returns serialized object representing this drafted item.



351
352
353
354
355
356
357
358
359
# File 'lib/draftsman/model.rb', line 351

def object_attrs_for_draft_record(object = nil)
  object ||= self

  _attrs = object.attributes.except(*self.class.draftsman_options[:skip]).tap do |attributes|
    self.class.serialize_attributes_for_draftsman attributes
  end

  self.class.draft_class.object_col_is_json? ? _attrs : Draftsman.serializer.dump(_attrs)
end

#published?Boolean

Returns whether or not this item has been published at any point in its lifecycle.

Returns:

  • (Boolean)


362
363
364
# File 'lib/draftsman/model.rb', line 362

def published?
  self.published_at.present?
end

#trashed?Boolean

Returns whether or not this item has been trashed

Returns:

  • (Boolean)


367
368
369
# File 'lib/draftsman/model.rb', line 367

def trashed?
  send(self.class.trashed_at_attribute_name).present?
end