Class: Version

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
lib/paper_trail/version.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.with_item_keys(item_type, item_id) ⇒ Object



6
7
8
# File 'lib/paper_trail/version.rb', line 6

def self.with_item_keys(item_type, item_id)
  scoped(:conditions => { :item_type => item_type, :item_id => item_id })
end

Instance Method Details

#changesetObject

Returns what changed in this version of the item. Cf. ‘ActiveModel::Dirty#changes`. Returns nil if your `versions` table does not have an `object_changes` text column.



85
86
87
88
89
90
91
92
93
# File 'lib/paper_trail/version.rb', line 85

def changeset
  if self.class.column_names.include? 'object_changes'
    if changes = object_changes
      HashWithIndifferentAccess[YAML::load(changes)]
    else
      {}
    end
  end
end

#indexObject



118
119
120
# File 'lib/paper_trail/version.rb', line 118

def index
  sibling_versions.select(:id).order("id ASC").map(&:id).index(self.id)
end

#nextObject



110
111
112
# File 'lib/paper_trail/version.rb', line 110

def next
  sibling_versions.subsequent(self).first
end

#originatorObject

Returns who put the item into the state stored in this version.



96
97
98
# File 'lib/paper_trail/version.rb', line 96

def originator
  previous.try :whodunnit
end

#previousObject



114
115
116
# File 'lib/paper_trail/version.rb', line 114

def previous
  sibling_versions.preceding(self).first
end

#reify(options = {}) ⇒ Object

Restore the item from this version.

This will automatically restore all :has_one associations as they were “at the time”, if they are also being versioned by PaperTrail. NOTE: this isn’t always guaranteed to work so you can either change the lookback period (from the default 3 seconds) or opt out.

Options: :has_one set to ‘false` to opt out of has_one reification.

set to a float to change the lookback time (check whether your db supports
sub-second datetimes if you want them).


34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/paper_trail/version.rb', line 34

def reify(options = {})
  without_identity_map do
    options[:has_one] = 3 if options[:has_one] == true
    options.reverse_merge! :has_one => false

    unless object.nil?
      attrs = YAML::load object

      # Normally a polymorphic belongs_to relationship allows us
      # to get the object we belong to by calling, in this case,
      # +item+.  However this returns nil if +item+ has been
      # destroyed, and we need to be able to retrieve destroyed
      # objects.
      #
      # In this situation we constantize the +item_type+ to get hold of
      # the class...except when the stored object's attributes
      # include a +type+ key.  If this is the case, the object
      # we belong to is using single table inheritance and the
      # +item_type+ will be the base class, not the actual subclass.
      # If +type+ is present but empty, the class is the base class.

      if item
        model = item
      else
        inheritance_column_name = item_type.constantize.inheritance_column
        class_name = attrs[inheritance_column_name].blank? ? item_type : attrs[inheritance_column_name]
        klass = class_name.constantize
        model = klass.new
      end

      attrs.each do |k, v|
        begin
          model.send :write_attribute, k.to_sym , v
        rescue NoMethodError
          logger.warn "Attribute #{k} does not exist on #{item_type} (Version id: #{id})."
        end
      end

      model.version = self

      unless options[:has_one] == false
        reify_has_ones model, options[:has_one]
      end

      model
    end
  end
end

#sibling_versionsObject



106
107
108
# File 'lib/paper_trail/version.rb', line 106

def sibling_versions
  self.class.with_item_keys(item_type, item_id)
end

#terminatorObject

Returns who changed the item from the state it had in this version. This is an alias for ‘whodunnit`.



102
103
104
# File 'lib/paper_trail/version.rb', line 102

def terminator
  whodunnit
end