module Mongoid::Versioning

Include this module to get automatic versioning of root level documents. This will add a version field to the Document and a has_many association with all the versions contained in it.

Public Instance Methods

revise() click to toggle source

Create a new version of the Document. This will load the previous document from the database and set it as the next version before saving the current document. It then increments the version number. If a max_versions limit is set in the model and it's exceeded, the oldest version gets discarded.

@example Revise the document.

person.revise

@since 1.0.0

# File lib/mongoid/versioning.rb, line 35
def revise
  previous = previous_revision
  if previous && versioned_attributes_changed?
    new_version = versions.build(
      previous.versioned_attributes, without_protection: true
    )
    new_version._id = nil
    if version_max.present? && versions.length > version_max
      deleted = versions.first
      if deleted.paranoid?
        versions.delete_one(deleted)
        collection.find(atomic_selector).
          update({ "$pull" => { "versions" => { "version" => deleted.version }}})
      else
        versions.delete(deleted)
      end
    end
    self.version = (version || 1 ) + 1
  end
end
revise!() click to toggle source

Forces the creation of a new version of the Document, regardless of whether a change was actually made.

@example Revise the document.

person.revise!

@since 2.2.1

# File lib/mongoid/versioning.rb, line 63
def revise!
  versions.build(
    (previous_revision || self).versioned_attributes, without_protection: true
  )
  versions.shift if version_max.present? && versions.length > version_max
  self.version = (version || 1 ) + 1
  save
end
versioned_attributes() click to toggle source

Filters the results of attributes by removing any fields that should not be versioned.

@return [ Hash ] A hash of versioned attributes.

@since 2.1.0

# File lib/mongoid/versioning.rb, line 88
def versioned_attributes
  only_versioned_attributes(attributes)
end
versioned_attributes_changed?() click to toggle source

Check if any versioned fields have been modified. This is similar to changed?, except this method also ignores fields set to be ignored by versioning.

@return [ Boolean ] Whether fields that will be versioned have changed.

@since 2.1.0

# File lib/mongoid/versioning.rb, line 99
def versioned_attributes_changed?
  !versioned_changes.empty?
end
versioned_changes() click to toggle source

Filters the results of changes by removing any fields that should not be versioned.

@return [ Hash ] A hash of versioned changed attributes.

@since 2.1.0

# File lib/mongoid/versioning.rb, line 78
def versioned_changes
  only_versioned_attributes(changes.except("updated_at"))
end
versionless() { |self| ... } click to toggle source

Executes a block that temporarily disables versioning. This is for cases where you do not want to version on every save.

@example Execute a save without versioning.

person.versionless(&:save)

@return [ Object ] The document or result of the block execution.

@since 2.0.0

# File lib/mongoid/versioning.rb, line 112
def versionless
  @versionless = true
  result = yield(self) if block_given?
  @versionless = false
  result || self
end

Private Instance Methods

add_versioned_attribute(versioned, name, value) click to toggle source

Add the versioned attribute. Will work now for localized fields.

@api private

@example Add the versioned attribute.

model.add_versioned_attribute({}, "name", "test")

@param [ Hash ] versioned The versioned attributes. @param [ String ] name The name of the field. @param [ Object ] value The value for the field.

@since 3.0.10

# File lib/mongoid/versioning.rb, line 192
def add_versioned_attribute(versioned, name, value)
  field = fields[name]
  if field && field.localized?
    versioned["#{name}_translations"] = value
  else
    versioned[name] = value if !field || field.versioned?
  end
end
only_versioned_attributes(hash) click to toggle source

Filters fields that should not be versioned out of an attributes hash. Dynamic attributes are always versioned.

@param [ Hash ] A hash with field names as keys.

@return [ Hash ] The hash without non-versioned columns.

@since 2.1.0

# File lib/mongoid/versioning.rb, line 172
def only_versioned_attributes(hash)
  versioned = {}
  hash.except("versions").each_pair do |name, value|
    add_versioned_attribute(versioned, name, value)
  end
  versioned
end
previous_revision() click to toggle source

Find the previous version of this document in the database, or if the document had been saved without versioning return the persisted one.

@example Find the last version.

document.find_last_version

@return [ Document, nil ] The previously saved document.

@since 2.0.0

# File lib/mongoid/versioning.rb, line 130
def previous_revision
  _loading_revision do
    self.class.unscoped.
      where(_id: id).
      any_of({ version: version }, { version: nil }).first
  end
end
revisable?() click to toggle source

Is the document able to be revised? This is true if the document has changed and we have not explicitly told it not to version.

@example Is the document revisable?

document.revisable?

@return [ true, false ] If the document is revisable.

@since 2.0.0

# File lib/mongoid/versioning.rb, line 147
def revisable?
  versioned_attributes_changed? && !versionless?
end
versionless?() click to toggle source

Are we in versionless mode? This is true if in a versionless block on the document.

@example Is the document in versionless mode?

document.versionless?

@return [ true, false ] Is the document not currently versioning.

@since 2.0.0

# File lib/mongoid/versioning.rb, line 160
def versionless?
  @versionless ||= false
end