Module: ActiveRecord::Acts::Versioned::Behaviors

Extended by:
ActiveSupport::Concern
Defined in:
lib/acts_as_versioned.rb

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#altered?Boolean

Returns:

  • (Boolean)


328
329
330
# File 'lib/acts_as_versioned.rb', line 328

def altered?
  changed.map { |c| self.class.versioned_columns.map(&:name).include?(c) & !self.class.version_except_columns.include?(c) }.any?
end

#clear_old_versionsObject

Clears old revisions if a limit is set with the :limit option in acts_as_versioned. Override this method to set your own criteria for clearing old versions.



286
287
288
289
290
291
292
# File 'lib/acts_as_versioned.rb', line 286

def clear_old_versions
  return if self.class.max_version_limit == 0
  excess_baggage = send(self.class.version_column).to_i - self.class.max_version_limit
  if excess_baggage > 0
    self.class.versioned_class.delete_all ["#{self.class.version_column} <= ? and #{self.class.versioned_foreign_key} = ?", excess_baggage, id]
  end
end

#clone_versioned_model(orig_model, new_model) ⇒ Object

Clones a model. Used when saving a new version or reverting a model’s version.



333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
# File 'lib/acts_as_versioned.rb', line 333

def clone_versioned_model(orig_model, new_model)
  self.class.versioned_columns.each do |col|
    next unless orig_model.has_attribute?(col.name)
    define_method(new_model, col.name.to_sym)
    new_model.send("#{col.name.to_sym}=", orig_model.send(col.name))
  end

  if orig_model.is_a?(self.class.versioned_class)
    new_model[new_model.class.inheritance_column] = orig_model[self.class.versioned_inheritance_column]
  elsif new_model.is_a?(self.class.versioned_class)
    sym = self.class.versioned_inheritance_column.to_sym
    define_method new_model, sym
    new_model.send("#{sym}=", orig_model[orig_model.class.inheritance_column]) if orig_model[orig_model.class.inheritance_column]
  end
end

#define_method(object, method) ⇒ Object



349
350
351
352
353
# File 'lib/acts_as_versioned.rb', line 349

def define_method(object, method)
  return if object.methods.include? method
  metaclass = class << object; self; end
  metaclass.send :attr_accessor, method
end

#empty_callbackObject



393
394
# File 'lib/acts_as_versioned.rb', line 393

def empty_callback()
end

#revert_to(version) ⇒ Object

Reverts a model to a given version. Takes either a version number or an instance of the versioned model



295
296
297
298
299
300
301
302
303
304
# File 'lib/acts_as_versioned.rb', line 295

def revert_to(version)
  if version.is_a?(self.class.versioned_class)
    return false unless version.send(self.class.versioned_foreign_key) == id and !version.new_record?
  else
    return false unless version = versions.where(self.class.version_column => version).first
  end
  self.clone_versioned_model(version, self)
  send("#{self.class.version_column}=", version.send(self.class.version_column))
  true
end

#revert_to!(version) ⇒ Object

Reverts a model to a given version and saves the model. Takes either a version number or an instance of the versioned model



308
309
310
# File 'lib/acts_as_versioned.rb', line 308

def revert_to!(version)
  revert_to(version) ? save_without_revision : false
end

#save_versionObject

Saves a version of the model in the versioned table. This is called in the after_save callback by default



273
274
275
276
277
278
279
280
281
282
# File 'lib/acts_as_versioned.rb', line 273

def save_version
  if @saving_version
    @saving_version = nil
    rev = self.class.versioned_class.new
    clone_versioned_model(self, rev)
    rev.send("#{self.class.version_column}=", send(self.class.version_column))
    rev.send("#{self.class.versioned_foreign_key}=", id)
    rev.save
  end
end

#save_version?Boolean

Checks whether a new version shall be saved or not. Calls version_condition_met? and changed?.

Returns:

  • (Boolean)


356
357
358
# File 'lib/acts_as_versioned.rb', line 356

def save_version?
  version_condition_met? && altered?
end

#save_without_revisionObject

Temporarily turns off Optimistic Locking while saving. Used when reverting so that a new version is not created.



313
314
315
316
317
318
# File 'lib/acts_as_versioned.rb', line 313

def save_without_revision
  save_without_revision!
  true
rescue
  false
end

#save_without_revision!Object



320
321
322
323
324
325
326
# File 'lib/acts_as_versioned.rb', line 320

def save_without_revision!
  without_locking do
    without_revision do
      save!
    end
  end
end

#version_condition_met?Boolean

Checks condition set in the :if option to check whether a revision should be created or not. Override this for custom version condition checking.

Returns:

  • (Boolean)


362
363
364
365
366
367
368
369
370
371
# File 'lib/acts_as_versioned.rb', line 362

def version_condition_met?
  case
    when version_condition.is_a?(Symbol)
      send(version_condition)
    when version_condition.respond_to?(:call) && (version_condition.arity == 1 || version_condition.arity == -1)
      version_condition.call(self)
    else
      version_condition
  end
end

#without_locking(&block) ⇒ Object

Turns off optimistic locking for the duration of the block

@foo.without_locking do
  @foo.save
end


389
390
391
# File 'lib/acts_as_versioned.rb', line 389

def without_locking(&block)
  self.class.without_locking(&block)
end

#without_revision(&block) ⇒ Object

Executes the block with the versioning callbacks disabled.

@foo.without_revision do
  @foo.save
end


379
380
381
# File 'lib/acts_as_versioned.rb', line 379

def without_revision(&block)
  self.class.without_revision(&block)
end