Module: Logidze::Model

Extended by:
ActiveSupport::Concern
Defined in:
lib/logidze/model.rb

Overview

Extends model with methods to browse history

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

TIME_FACTOR =

Use this to convert Ruby time to milliseconds

1_000

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#logidze_requested_tsObject

Returns the value of attribute logidze_requested_ts.



45
46
47
# File 'lib/logidze/model.rb', line 45

def logidze_requested_ts
  @logidze_requested_ts
end

Instance Method Details

#association(name) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/logidze/model.rb', line 138

def association(name)
  association = super

  return association unless Logidze.associations_versioning

  should_appply_logidze =
    logidze_past? &&
    association.klass.respond_to?(:has_logidze?) &&
    !association.singleton_class.include?(Logidze::VersionedAssociation)

  return association unless should_appply_logidze

  association.singleton_class.prepend Logidze::VersionedAssociation

  if association.is_a? ActiveRecord::Associations::CollectionAssociation
    association.singleton_class.prepend(
      Logidze::VersionedAssociation::CollectionAssociation
    )
  end

  association
end

#at(ts) ⇒ Object

Return a dirty copy of record at specified time If time is less then the first version, then return nil. If time is greater then the last version, then return self.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/logidze/model.rb', line 50

def at(ts)
  ts = parse_time(ts)

  return nil unless log_data.exists_ts?(ts)

  if log_data.current_ts?(ts)
    self.logidze_requested_ts = ts
    return self
  end

  version = log_data.find_by_time(ts).version

  object_at = dup
  object_at.apply_diff(version, log_data.changes_to(version: version))
  object_at.id = id
  object_at.logidze_requested_ts = ts

  object_at
end

#at!(ts) ⇒ Object

Revert record to the version at specified time (without saving to DB)



71
72
73
74
75
76
77
78
79
# File 'lib/logidze/model.rb', line 71

def at!(ts)
  ts = parse_time(ts)
  return self if log_data.current_ts?(ts)
  return false unless log_data.exists_ts?(ts)

  version = log_data.find_by_time(ts).version

  apply_diff(version, log_data.changes_to(version: version))
end

#at_version(version) ⇒ Object

Return a dirty copy of specified version of record



82
83
84
85
86
87
88
# File 'lib/logidze/model.rb', line 82

def at_version(version)
  return self if log_data.version == version
  return nil unless log_data.find_by_version(version)

  object_at = dup
  object_at.apply_diff(version, log_data.changes_to(version: version))
end

#at_version!(version) ⇒ Object

Revert record to the specified version (without saving to DB)



91
92
93
94
95
96
# File 'lib/logidze/model.rb', line 91

def at_version!(version)
  return self if log_data.version == version
  return false unless log_data.find_by_version(version)

  apply_diff(version, log_data.changes_to(version: version))
end

#diff_from(ts) ⇒ Object

Return diff object representing changes since specified time.

Examples:


post.diff_from(2.days.ago)
#=> { "id" => 1, "changes" => { "title" => { "old" => "Hello!", "new" => "World" } } }


104
105
106
107
# File 'lib/logidze/model.rb', line 104

def diff_from(ts)
  ts = parse_time(ts)
  { "id" => id, "changes" => log_data.diff_from(time: ts) }
end

#redo!Object

Restore record to the future version (if ‘undo!` was applied) Return false if no future version found, otherwise return updated record.



119
120
121
122
123
# File 'lib/logidze/model.rb', line 119

def redo!
  version = log_data.next_version
  return false if version.nil?
  switch_to!(version.version)
end

#switch_to!(version, append: Logidze.append_on_undo) ⇒ Object

Restore record to the specified version. Return false if version is unknown.



127
128
129
130
131
132
133
134
135
136
# File 'lib/logidze/model.rb', line 127

def switch_to!(version, append: Logidze.append_on_undo)
  return false unless at_version(version)

  if append && version < log_version
    update!(log_data.changes_to(version: version))
  else
    at_version!(version)
    self.class.without_logging { save! }
  end
end

#undo!(append: Logidze.append_on_undo) ⇒ Object

Restore record to the previous version. Return false if no previous version found, otherwise return updated record.



111
112
113
114
115
# File 'lib/logidze/model.rb', line 111

def undo!(append: Logidze.append_on_undo)
  version = log_data.previous_version
  return false if version.nil?
  switch_to!(version.version, append: append)
end