module Mongoid::History::Trackable::MyInstanceMethods

Public Instance Methods

get_version(version) click to toggle source
# File lib/mongoid/history/trackable.rb, line 161
def get_version(version)
  track = history_tracks.first
  
  track.modified.keys.each do |key|
    track[key] = track.modified[key]
  end
  
  version -= 1
  
  if (version < 0)
    return nil
  end
  
  if (version >= history_tracks.count)
    version = history_tracks.count-1
  end
  
  for i in 1..version

    history_tracks[i].modified.keys.each do |key|
      track[key] = history_tracks[i].modified[key]
    end

    track.modified = history_tracks[i].modified
    track.original = history_tracks[i].original

  end

  track.version = version
  track
end
history_tracks() click to toggle source
# File lib/mongoid/history/trackable.rb, line 80
def history_tracks
  @history_tracks ||= Mongoid::History.tracker_class.where(:scope => history_trackable_options[:scope], :association_chain => association_hash)
end
redo!(modifier, options_or_version=nil) click to toggle source
# File lib/mongoid/history/trackable.rb, line 150
def redo!(modifier, options_or_version=nil)
  versions = get_versions_criteria(options_or_version).to_a
  versions.sort!{|v1, v2| v1.version <=> v2.version}

  versions.each do |v|
    redo_attr = v.redo_attr(modifier)
    self.attributes = redo_attr
  end
  save!
end
undo!(modifier, options_or_version=nil) click to toggle source

undo :from => 1, :to => 5 undo 4 undo :last => 10

# File lib/mongoid/history/trackable.rb, line 87
def undo!(modifier, options_or_version=nil)
  if (!options_or_version.is_a?(Hash))
    version = get_version(options_or_version.to_i)
    attrs = {}
    fields = history_tracks.first.modified.keys
    
    if history_trackable_options[:on] == :all

      fields.each do |k|
        if !history_trackable_options[:except].include?(k)
          if (!version.attributes[:modified].nil? && version.attributes[:modified].include?(k))
            attrs[k] = version.attributes[:modified][k]
          else
            attrs[k] = version.attributes[k]
          end
        end
      end
  
    else
  
      fields.each do |k|
        if history_trackable_options[:on].include?(k)
          
          if (!version.attributes[:modified].nil? && version.attributes[:modified].include?(k))
            attrs[k] = version.attributes[:modified][k]
          else
            attrs[k] = version.attributes[k]
          end
          
        end
      end
  
    end
    
    if history_trackable_options[:remember_attachment]
      
      addr = [Rails.root, '/public/', 'system/', 'store/', attachment_definitions.first.first.to_s, '/', id.to_s, '/', version.data_updated_at.to_i.to_s, '/'].join()
      Dir.chdir(addr)
      file_name = Dir.glob('*.*').first
      
      attach = File.new(addr + file_name) 
      data = attach
      
      attrs["data_file_name"] = file_name
      
    end
    
    self.update_attributes(attrs)
    
  else
    
    versions = get_versions_criteria(options_or_version).to_a
    versions.sort!{|v1, v2| v2.version <=> v1.version}
    
    versions.each do |v|
      undo_attr = v.undo_attr(modifier)
      self.attributes = v.undo_attr(modifier)
    end
  end

  save!
end

Private Instance Methods

association_hash(node=self) click to toggle source
# File lib/mongoid/history/trackable.rb, line 254
def association_hash(node=self)

  # We prefer to look up associations through the parent record because
  # we're assured, through the object creation, it'll exist. Whereas we're not guarenteed
  # the child to parent (embedded_in, belongs_to) relation will be defined
  if node._parent
    meta = _parent.relations.values.select do |relation|
      relation.class_name == node.class.to_s
    end.first
  end

  # if root node has no meta, and should use class name instead
  name = meta ? meta.key.to_s : node.class.name

  { 'name' => name, 'id' => node.id}
end
clear_memoization() click to toggle source
# File lib/mongoid/history/trackable.rb, line 354
def clear_memoization
  @history_tracker_attributes =  nil
  @modified_attributes_for_create = nil
  @modified_attributes_for_update = nil
  @history_tracks = nil
end
fill_remember_only_attributes(for_update) click to toggle source
# File lib/mongoid/history/trackable.rb, line 228
def fill_remember_only_attributes(for_update)
  
  history_trackable_options[:except_but_remember].each do |key|
    
    if (!for_update.include?(key))
      for_update[key] = self[key]
    end
    
  end
  
end
get_versions_criteria(options_or_version) click to toggle source
# File lib/mongoid/history/trackable.rb, line 195
def get_versions_criteria(options_or_version)
  if options_or_version.is_a? Hash
    options = options_or_version
    if options[:from] && options[:to]
      lower = options[:from] >= options[:to] ? options[:to] : options[:from]
      upper = options[:from] <  options[:to] ? options[:to] : options[:from]
      versions = history_tracks.where( :version.in => (lower .. upper).to_a )
    elsif options[:last]
      versions = history_tracks.limit( options[:last] )
    else
      raise "Invalid options, please specify (:from / :to) keys or :last key."
    end
  else
    options_or_version = options_or_version.to_a if options_or_version.is_a?(Range)
    version_field_name = history_trackable_options[:version_field]
    version = options_or_version || self.attributes[version_field_name] || self.attributes[version_field_name.to_s]
    version = [ version ].flatten
    versions = history_tracks.where(:version.in => version)
  end
  versions.desc(:version)
end
history_tracker_attributes(method) click to toggle source
# File lib/mongoid/history/trackable.rb, line 309
def history_tracker_attributes(method)
  return @history_tracker_attributes if @history_tracker_attributes

  @history_tracker_attributes = {
    :association_chain  => traverse_association_chain,
    :scope              => history_trackable_options[:scope],
    :modifier           => send(history_trackable_options[:modifier_field])
  }

  original, modified = transform_changes(case method
    when :destroy then modified_attributes_for_destroy
    when :create then modified_attributes_for_create
    else modified_attributes_for_update
  end)

  fill_remember_only_attributes(modified)

  @history_tracker_attributes[:original] = original
  @history_tracker_attributes[:modified] = modified
  @history_tracker_attributes
end
modified_attributes_for_create() click to toggle source
# File lib/mongoid/history/trackable.rb, line 291
def modified_attributes_for_create
  @modified_attributes_for_create ||= attributes.inject({}) do |h, pair|
    k,v =  pair
    h[k] = [nil, v]
    h
  end.reject do |k, v|
    history_trackable_options[:except].include?(k)
  end
end
modified_attributes_for_destroy() click to toggle source
# File lib/mongoid/history/trackable.rb, line 301
def modified_attributes_for_destroy
  @modified_attributes_for_destroy ||= attributes.inject({}) do |h, pair|
    k,v =  pair
    h[k] = [nil, v]
    h
  end
end
modified_attributes_for_update() click to toggle source
# File lib/mongoid/history/trackable.rb, line 271
def modified_attributes_for_update
  @modified_attributes_for_update = changes 

  if history_trackable_options[:on] == :all

    changes.each do |k, v|
      @modified_attributes_for_update.delete(k) if history_trackable_options[:except].include?(k)
    end

  else

    changes.each do |k, v|
      @modified_attributes_for_update.delete(k) if !history_trackable_options[:on].include?(k)
    end

  end
  
  @modified_attributes_for_update
end
remember_only?(attributes) click to toggle source
# File lib/mongoid/history/trackable.rb, line 217
def remember_only?(attributes)
  
  return false if history_trackable_options[:except_but_remember].nil? || history_trackable_options[:except_but_remember].blank?

  attributes.each do |k, v|
    return false if !history_trackable_options[:except_but_remember].include?(k.to_s)
  end
  
  true
end
should_track_update?() click to toggle source
# File lib/mongoid/history/trackable.rb, line 240
def should_track_update?
  for_update = modified_attributes_for_update
  
  return false if (remember_only?(for_update))
  
  track_history? && !for_update.blank?
end
track_create() click to toggle source
# File lib/mongoid/history/trackable.rb, line 339
def track_create
  return unless track_history?
  current_version = (self.send(history_trackable_options[:version_field]) || 0 ) + 1
  self.send("#{history_trackable_options[:version_field]}=", current_version)
  Mongoid::History.tracker_class.create!(history_tracker_attributes(:create).merge(:version => current_version, :action => "create", :trackable => self))
  clear_memoization
end
track_destroy() click to toggle source
# File lib/mongoid/history/trackable.rb, line 347
def track_destroy
  return unless track_history?
  current_version = (self.send(history_trackable_options[:version_field]) || 0 ) + 1
  Mongoid::History.tracker_class.create!(history_tracker_attributes(:destroy).merge(:version => current_version, :action => "destroy", :trackable => self))
  clear_memoization
end
track_update() click to toggle source
# File lib/mongoid/history/trackable.rb, line 331
def track_update
  return unless should_track_update?
  current_version = (self.send(history_trackable_options[:version_field]) || 0 ) + 1
  self.send("#{history_trackable_options[:version_field]}=", current_version)
  Mongoid::History.tracker_class.create!(history_tracker_attributes(:update).merge(:version => current_version, :action => "update", :trackable => self))
  clear_memoization
end
transform_changes(changes) click to toggle source
# File lib/mongoid/history/trackable.rb, line 361
def transform_changes(changes)
  original = {}
  modified = {}
  changes.each_pair do |k, v|
    o, m = v
    original[k] = o unless o.nil?
    modified[k] = m #unless m.nil?
  end

  return original.easy_diff modified
end
traverse_association_chain(node=self) click to toggle source
# File lib/mongoid/history/trackable.rb, line 248
def traverse_association_chain(node=self)
  list = node._parent ? traverse_association_chain(node._parent) : []
  list << association_hash(node)
  list
end