module ActiveRecord::Acts::Versioner::InstanceMethods

Attributes

acts_as_versioner_mode[RW]
acts_as_versioner_model[RW]

Public Instance Methods

get_current_version() click to toggle source

Returns the current version.

# File lib/acts_as_versioner/acts_as_versioner.rb, line 65
  def get_current_version
instance_eval(self.versioned_class_name).where([self.versioned_foreign_key + ' = ?', self.id]).order(Arel.sql("#{ActiveRecord::Acts::Versioner::configurator[:default_versioned_updated_at]} desc, id desc")).first
  end
get_versions() click to toggle source

Returns all versions of a model.

# File lib/acts_as_versioner/acts_as_versioner.rb, line 70
  def get_versions
instance_eval(self.versioned_class_name).where([self.versioned_foreign_key + ' = ?', self.id]).order(Arel.sql("#{ActiveRecord::Acts::Versioner::configurator[:default_versioned_updated_at]} asc, id asc")).all
  end
get_versions_children() click to toggle source

This methods returns all versions of associated tables (table that belong to the existing model).

# File lib/acts_as_versioner/acts_as_versioner.rb, line 75
  def get_versions_children
    associations = Hash.new # result hash
    stack = Array.new # Stack of the same algorithm.

# Initiate algorithm with the used model
    versions = instance_eval(self.versioned_class_name).where([self.versioned_foreign_key + ' = ?', self.id]).order(Arel.sql("#{ActiveRecord::Acts::Versioner::configurator[:default_versioned_updated_at]} asc, #{ActiveRecord::Acts::Versioner::configurator[:default_versioned_created_at]} asc")).all
    associations[self.versioned_class_name] = versions # Caching itself in the result hash
    stack.push self.class => versions # Setting itself onto the stack

# Main loop of the algorith
    while class_struct = stack.pop
      class_name = nil
      data_set = nil

      class_struct.each do |key_class_name, value_data_set|
        class_name = key_class_name
        data_set = value_data_set
      end

  # Read all assocations
      reflection_assoc = Array.new
      reflection_assoc.concat(class_name.reflect_on_all_associations(:has_one))
      reflection_assoc.concat(class_name.reflect_on_all_associations(:has_many))
      reflection_assoc.compact!

  # Iterate through all associations
      reflection_assoc.each do |association|
        association_klass = association.klass
    # Is there a versioning table? If yes, go back to the beginning of the iteration..
    if association_klass.to_s.include?("version") then next end
        child_associations_has_one = association_klass.reflect_on_all_associations(:has_one)
        child_associations_has_many = association_klass.reflect_on_all_associations(:has_many)

    # Does the associated table have further associated tables and did they already be iterated through?
        if (child_associations_has_one.empty? || child_associations_has_many.empty?) && associations[association_klass.versioned_class_name] != nil then next end

        new_data_set = Array.new
    # Check if the table has been visited already. If yes, complete the data sets -> Does only happen if we have a table without associations.
        if associations[association_klass.versioned_class_name] != nil then new_data_set = associations[association_klass.versioned_class_name] end

    foreign_ids = []
    data_set.each { |data|
      foreign_ids << instance_eval("data." + class_name.to_s.tableize.singularize.downcase + "_id.to_s")
    }

    unless foreign_ids.blank?
          tmp_new_data_set = association_klass.versioned_class.where(["#{class_name.to_s.tableize.singularize.downcase}_id IN (?)", foreign_ids]).order(Arel.sql("#{ActiveRecord::Acts::Versioner::configurator[:default_versioned_updated_at]} asc, #{ActiveRecord::Acts::Versioner::configurator[:default_versioned_created_at]} asc")).all
          unless tmp_new_data_set.blank? then new_data_set.concat(tmp_new_data_set) end
    end

    # Cache the found data sets into the result hash
        associations[association_klass.versioned_class_name] = new_data_set
    # Additionally found data sets get saved on the stack for the next iteration
        stack.push association_klass => new_data_set
      end
    end

# Remove all double entries
associations.each do |class_name_to_s, versionArray|
      versionArray.uniq!
    end

    return associations
  end

Private Instance Methods

a_d() click to toggle source

This method overrides the default method “after_destroy” of the ActiveRecord class. It is invoked after the actual destroying has token place and serves to execute the versioning.

# File lib/acts_as_versioner/acts_as_versioner.rb, line 162
def a_d
  do_versioning
end
a_s() click to toggle source

This method overrides the default method “after_save” of the ActiveRecord class. It is invoked after the actual saving has token place and serves to execute the versioning.

# File lib/acts_as_versioner/acts_as_versioner.rb, line 156
def a_s
  do_versioning
end
b_d() click to toggle source

This method overrides the default method “before_destroy” of the ActiveRecord class. It is invoked before the actual destroying takes place and serves to preparing the versioning.

# File lib/acts_as_versioner/acts_as_versioner.rb, line 150
def b_d
  prepare_versioning 2
end
b_s() click to toggle source

This method overrides the default method “before_save” of the ActiveRecord class. It is invoked before the actual saving takes place and serves to preparing the versioning.

# File lib/acts_as_versioner/acts_as_versioner.rb, line 144
def b_s
  prepare_versioning
end
do_versioning() click to toggle source

In this method the versioning is happening. It expects a copy of the current object in the variable @acts_as_versioner_mode. It will be invoked after the method “prepare_versioning”

# File lib/acts_as_versioner/acts_as_versioner.rb, line 178
    def do_versioning
      attributes = Hash.new
  # Save variables and the values in a hash
      @acts_as_versioner_model.attributes.each do |attribute, value|
        attributes[attribute] = value unless attribute == "id" # ID has to be excluded because MassAssignment warning...
      end

      @acts_as_versioner_model = nil

      attributes[self.versioned_foreign_key] = self.id
      attributes[:action] = @acts_as_versioner_mode

# Conserve the created_at field in the versions table
attributes[ActiveRecord::Acts::Versioner::configurator[:default_versioned_created_at].to_sym] = self[ActiveRecord::Acts::Versioner::configurator[:default_versioned_created_at].to_sym]

      modelversion = instance_eval(self.versioned_class_name).new(attributes)
      modelversion.save(:validate => false)
    end
prepare_versioning(mode = 0) click to toggle source

This method is preparing the versioning. It copies the current object and saves it into a variable. For the number it is assumed to be between 0 and 2 depending on the mode (0 = insert, 1 = update, 2 = delete).

# File lib/acts_as_versioner/acts_as_versioner.rb, line 168
    def prepare_versioning(mode = 0)
      @acts_as_versioner_mode = mode # mode : 0 = insert, 1 = update, 2 = delete
      @acts_as_versioner_model = self.dup
@acts_as_versioner_model.updated_at = Time.now

      if mode == 0 && self.id != nil then @acts_as_versioner_mode = 1 end  
    end